forked from FOSS/BangleApps
Add HID apps
parent
26114902d4
commit
f28c141f22
22
apps.json
22
apps.json
|
@ -162,6 +162,28 @@
|
||||||
{"name":"*swatch","url":"stopwatch-icon.js","evaluate":true}
|
{"name":"*swatch","url":"stopwatch-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{ "id": "hidmsic",
|
||||||
|
"name": "Bluetooth Music Controls",
|
||||||
|
"icon": "hid-music.png",
|
||||||
|
"description": "Enable HID in settings, pair with your phone, then use this app to control music from your watch!",
|
||||||
|
"tags": "bluetooth",
|
||||||
|
"storage": [
|
||||||
|
{"name":"+hidmsic","url":"hid-music.json"},
|
||||||
|
{"name":"-hidmsic","url":"hid-music.js"},
|
||||||
|
{"name":"*hidmsic","url":"hid-music-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "id": "hidkbd",
|
||||||
|
"name": "Bluetooth Keyboard",
|
||||||
|
"icon": "hid-keyboard.png",
|
||||||
|
"description": "Enable HID in settings, pair with your phone/PC, then use this app to control other apps",
|
||||||
|
"tags": "bluetooth",
|
||||||
|
"storage": [
|
||||||
|
{"name":"+hidkbd","url":"hid-keyboard.json"},
|
||||||
|
{"name":"-hidkbd","url":"hid-keyboard.js"},
|
||||||
|
{"name":"*hidkbd","url":"hid-keyboard-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "id": "animals",
|
{ "id": "animals",
|
||||||
"name": "Animals Game",
|
"name": "Animals Game",
|
||||||
"icon": "animals.png",
|
"icon": "animals.png",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwhC/AH4A/AHeIDC+AC60IC/51ELoIXTCYMIDISLpC/67dxAAJHBYsLhAYKLhgXXHhWAdoQbBApAvhBgYcCAogXkI64XYhDtII/oMUERTyDABJ0FPI4A/AH4A/AGY="))
|
|
@ -0,0 +1,86 @@
|
||||||
|
var storage = require('Storage');
|
||||||
|
|
||||||
|
const settings = storage.readJSON('@settings') || { HID: false };
|
||||||
|
|
||||||
|
var sendHid, next, prev, toggle, up, down, profile;
|
||||||
|
|
||||||
|
if (settings.HID) {
|
||||||
|
profile = 'Keyboard';
|
||||||
|
sendHid = function (code, cb) {
|
||||||
|
try {
|
||||||
|
NRF.sendHIDReport([2,0,0,code,0,0,0,0,0], () => {
|
||||||
|
NRF.sendHIDReport([2,0,0,0,0,0,0,0,0], () => {
|
||||||
|
if (cb) cb();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch(e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
next = function (cb) { sendHid(0x4f, cb); };
|
||||||
|
prev = function (cb) { sendHid(0x50, cb); };
|
||||||
|
toggle = function (cb) { sendHid(0x2c, cb); };
|
||||||
|
up = function (cb) {sendHid(0x52, cb); };
|
||||||
|
down = function (cb) { sendHid(0x51, cb); };
|
||||||
|
} else {
|
||||||
|
E.showMessage('HID disabled');
|
||||||
|
setTimeout(load, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawApp() {
|
||||||
|
g.clear();
|
||||||
|
g.setFont("6x8",2);
|
||||||
|
g.setFontAlign(0,0);
|
||||||
|
g.drawString(profile, 120, 120);
|
||||||
|
const d = g.getWidth() - 18;
|
||||||
|
|
||||||
|
function c(a) {
|
||||||
|
return {
|
||||||
|
width: 8,
|
||||||
|
height: a.length,
|
||||||
|
bpp: 1,
|
||||||
|
buffer: (new Uint8Array(a)).buffer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
g.drawImage(c([16,56,124,254,16,16,16,16]),d,40);
|
||||||
|
g.drawImage(c([16,16,16,16,254,124,56,16]),d,194);
|
||||||
|
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next) {
|
||||||
|
setWatch(function(e) {
|
||||||
|
var len = e.time - e.lastTime;
|
||||||
|
if (len > 0.3 && len < 0.9) {
|
||||||
|
E.showMessage('prev');
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
prev(() => {});
|
||||||
|
} else {
|
||||||
|
E.showMessage('up');
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
up(() => {});
|
||||||
|
}
|
||||||
|
}, BTN1, { edge:"falling",repeat:true,debounce:50});
|
||||||
|
|
||||||
|
setWatch(function(e) {
|
||||||
|
var len = e.time - e.lastTime;
|
||||||
|
if (len > 0.3 && len < 0.9) {
|
||||||
|
E.showMessage('next');
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
next(() => {});
|
||||||
|
} else {
|
||||||
|
E.showMessage('down');
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
down(() => {});
|
||||||
|
}
|
||||||
|
}, BTN3, { edge:"falling",repeat:true,debounce:50});
|
||||||
|
|
||||||
|
setWatch(function(e) {
|
||||||
|
E.showMessage('toggle')
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
toggle();
|
||||||
|
}, BTN2, { edge:"falling",repeat:true,debounce:50});
|
||||||
|
|
||||||
|
drawApp();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "Keyboard Control",
|
||||||
|
"icon": "*hidkbd",
|
||||||
|
"src": "-hidkbd"
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 506 B |
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwhC/AH4A5xGICquZzAVUAAIXQCogXQCoxHPCox0BxIXNxIVFBAQXPUAwXPBw4XowAvuC/4X/C9sIC6kIxGZzIXSFgIWBC6QWEC6RECAAOJwAXQFwoXLxAqBC4MICweZCxhWEC4mICxxuDA4I3BCxQ/FQxpyEK6AucC4idMI5OICyQwBQpgA/AH4Au"))
|
|
@ -0,0 +1,85 @@
|
||||||
|
var storage = require('Storage');
|
||||||
|
|
||||||
|
const settings = storage.readJSON('@settings') || { HID: false };
|
||||||
|
|
||||||
|
var sendHid, next, prev, toggle, up, down, profile;
|
||||||
|
|
||||||
|
if (settings.HID) {
|
||||||
|
profile = 'Music';
|
||||||
|
sendHid = function (code, cb) {
|
||||||
|
try {
|
||||||
|
NRF.sendHIDReport([1,code], () => {
|
||||||
|
NRF.sendHIDReport([1,0], () => {
|
||||||
|
if (cb) cb();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch(e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
next = function (cb) { sendHid(0x01, cb); };
|
||||||
|
prev = function (cb) { sendHid(0x02, cb); };
|
||||||
|
toggle = function (cb) { sendHid(0x10, cb); };
|
||||||
|
up = function (cb) {sendHid(0x40, cb); };
|
||||||
|
down = function (cb) { sendHid(0x80, cb); };
|
||||||
|
} else {
|
||||||
|
E.showMessage('HID disabled');
|
||||||
|
setTimeout(load, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawApp() {
|
||||||
|
g.clear();
|
||||||
|
g.setFont("6x8",2);
|
||||||
|
g.setFontAlign(0,0);
|
||||||
|
g.drawString(profile, 120, 120);
|
||||||
|
const d = g.getWidth() - 18;
|
||||||
|
|
||||||
|
function c(a) {
|
||||||
|
return {
|
||||||
|
width: 8,
|
||||||
|
height: a.length,
|
||||||
|
bpp: 1,
|
||||||
|
buffer: (new Uint8Array(a)).buffer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
g.drawImage(c([16,56,124,254,16,16,16,16]),d,40);
|
||||||
|
g.drawImage(c([16,16,16,16,254,124,56,16]),d,194);
|
||||||
|
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next) {
|
||||||
|
setWatch(function(e) {
|
||||||
|
var len = e.time - e.lastTime;
|
||||||
|
if (len > 0.3 && len < 0.9) {
|
||||||
|
E.showMessage('prev');
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
prev(() => {});
|
||||||
|
} else {
|
||||||
|
E.showMessage('up');
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
up(() => {});
|
||||||
|
}
|
||||||
|
}, BTN1, { edge:"falling",repeat:true,debounce:50});
|
||||||
|
|
||||||
|
setWatch(function(e) {
|
||||||
|
var len = e.time - e.lastTime;
|
||||||
|
if (len > 0.3 && len < 0.9) {
|
||||||
|
E.showMessage('next');
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
next(() => {});
|
||||||
|
} else {
|
||||||
|
E.showMessage('down');
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
down(() => {});
|
||||||
|
}
|
||||||
|
}, BTN3, { edge:"falling",repeat:true,debounce:50});
|
||||||
|
|
||||||
|
setWatch(function(e) {
|
||||||
|
E.showMessage('toggle')
|
||||||
|
setTimeout(drawApp, 1000);
|
||||||
|
toggle();
|
||||||
|
}, BTN2, { edge:"falling",repeat:true,debounce:50});
|
||||||
|
|
||||||
|
drawApp();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "Music Control",
|
||||||
|
"icon": "*hidmsic",
|
||||||
|
"src": "-hidmsic"
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 632 B |
|
@ -1,10 +1,14 @@
|
||||||
(function() {
|
(function() {
|
||||||
var s = require('Storage').readJSON('@settings');
|
var s = require('Storage').readJSON('@settings');
|
||||||
|
var adv = { uart: true };
|
||||||
if (s.HID) {
|
if (s.HID) {
|
||||||
|
// Report from https://notes.iopush.net/custom-usb-hid-device-descriptor-media-keyboard/
|
||||||
Bangle.HID = new Uint8Array([
|
Bangle.HID = new Uint8Array([
|
||||||
|
// Keyboard Controls
|
||||||
0x05, 0x01,
|
0x05, 0x01,
|
||||||
0x09, 0x06,
|
0x09, 0x06,
|
||||||
0xA1, 0x01,
|
0xA1, 0x01,
|
||||||
|
0x85, 0x02,
|
||||||
0x05, 0x07,
|
0x05, 0x07,
|
||||||
0x19, 0xe0,
|
0x19, 0xe0,
|
||||||
0x29, 0xe7,
|
0x29, 0xe7,
|
||||||
|
@ -39,17 +43,42 @@
|
||||||
0x75, 0x08,
|
0x75, 0x08,
|
||||||
0x95, 0x02,
|
0x95, 0x02,
|
||||||
0xB1, 0x02,
|
0xB1, 0x02,
|
||||||
|
0xC0,
|
||||||
|
|
||||||
|
// Music Controls
|
||||||
|
0x05, 0x0C,
|
||||||
|
0x09, 0x01,
|
||||||
|
0xA1, 0x01,
|
||||||
|
0x85, 0x01,
|
||||||
|
0x15, 0x00,
|
||||||
|
0x25, 0x01,
|
||||||
|
0x75, 0x01,
|
||||||
|
0x95, 0x01,
|
||||||
|
0x09, 0xB5,
|
||||||
|
0x81, 0x02,
|
||||||
|
0x09, 0xB6,
|
||||||
|
0x81, 0x02,
|
||||||
|
0x09, 0xB7,
|
||||||
|
0x81, 0x02,
|
||||||
|
0x09, 0xB8,
|
||||||
|
0x81, 0x02,
|
||||||
|
0x09, 0xCD,
|
||||||
|
0x81, 0x02,
|
||||||
|
0x09, 0xE2,
|
||||||
|
0x81, 0x02,
|
||||||
|
0x09, 0xE9,
|
||||||
|
0x81, 0x02,
|
||||||
|
0x09, 0xEA,
|
||||||
|
0x81, 0x02,
|
||||||
0xC0
|
0xC0
|
||||||
]);
|
]);
|
||||||
NRF.setServices(undefined, {
|
adv.hid = Bangle.HID;
|
||||||
uart: true, hid: Bangle.HID,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
NRF.setServices(undefined, adv);
|
||||||
|
|
||||||
if (!s.vibrate) Bangle.buzz=()=>Promise.resolve();
|
if (!s.vibrate) Bangle.buzz=()=>Promise.resolve();
|
||||||
if (!s.beep) Bangle.beep=()=>Promise.resolve();
|
if (!s.beep) Bangle.beep=()=>Promise.resolve();
|
||||||
Bangle.setLCDTimeout(s.timeout);
|
Bangle.setLCDTimeout(s.timeout);
|
||||||
if (!s.timeout) Bangle.setLCDPower(1);
|
if (!s.timeout) Bangle.setLCDPower(1);
|
||||||
E.setTimeZone(s.timezone);
|
E.setTimeZone(s.timezone);
|
||||||
})();
|
})()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue