Merge branch 'espruino:master' into master

master
Peer David 2022-01-25 18:44:35 +01:00 committed by GitHub
commit e8918680b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 101 additions and 66 deletions

View File

@ -2,3 +2,4 @@
0.02: Stopped watchface from flashing every interval
0.03: Move to Bangle.setUI to launcher support
0.04: Tweaks for compatibility with BangleJS2
0.05: Time-word now readable on Bangle.js 2

View File

@ -46,7 +46,7 @@ const dy = big ? 22 : 16;
const fontSize = big ? 3 : 2; // "6x8"
const passivColor = 0x3186 /*grey*/ ;
const activeColorNight = 0xF800 /*red*/ ;
const activeColorDay = 0xFFFF /* white */;
const activeColorDay = g.theme.fg;
var hidxPrev;
var showDigitalTime = false;

View File

@ -1,7 +1,7 @@
{
"id": "impwclock",
"name": "Imprecise Word Clock",
"version": "0.04",
"version": "0.05",
"description": "Imprecise word clock for vacations, weekends, and those who never need accurate time.",
"icon": "clock-impword.png",
"type": "clock",

View File

@ -2,4 +2,5 @@
0.02: Corrected variable initialisation
0.03: Advertise app name, added screenshots
0.04: Advertise bar, GPS, HRM and mag services
0.05: Refactored for efficiency, corrected sensor value inaccuracies
0.05: Refactored for efficiency, corrected sensor value inaccuracies
0.06: User settings are written to persistent storage, loaded on app start

View File

@ -5,7 +5,9 @@ Collect all the sensor data from the Bangle.js 2, display the live readings in m
## Usage
The advertising packets will be recognised by [Pareto Anywhere](https://www.reelyactive.com/pareto/anywhere/) open source middleware and any other program which observes the standard packet types. Also convenient for testing individual sensors of the Bangle.js 2 via the menu interface.
The advertising packets will be recognised by [Pareto Anywhere](https://www.reelyactive.com/pareto/anywhere/) open source middleware and any other program which observes the standard packet types. See our [Bangle.js Development Guide](https://reelyactive.github.io/diy/banglejs-dev/) for details. Also convenient for testing individual sensors of the Bangle.js 2 via the menu interface.
![SensiBLE in Pareto Anywhere](/BangleApps/apps/sensible/screenshot-pareto-anywhere.png)
## Features
@ -22,7 +24,7 @@ in the menu display, and broadcasts all sensor data readings _except_ accelerati
## Controls
Browse and control sensors using the standard Espruino menu interface.
Browse and control sensors using the standard Espruino menu interface. By default, all sensors _except_ the accelerometer are disabled. Sensors can be individually enabled/disabled via the menu. These settings are written to persistent storage (flash) and will be applied each time the SensiBLE app is loaded.
## Requests

View File

@ -1,25 +1,28 @@
{
"id": "sensible",
"name": "SensiBLE",
"shortName": "SensiBLE",
"version": "0.05",
"description": "Collect, display and advertise real-time sensor data.",
"icon": "sensible.png",
"screenshots": [
{ "url": "screenshot-top.png" },
{ "url": "screenshot-acc.png" },
{ "url": "screenshot-bar.png" },
{ "url": "screenshot-gps.png" },
{ "url": "screenshot-hrm.png" },
{ "url": "screenshot-mag.png" }
],
"type": "app",
"tags": "tool,sensors,bluetooth",
"supports" : [ "BANGLEJS2" ],
"allow_emulator": true,
"readme": "README.md",
"storage": [
{ "name": "sensible.app.js", "url": "sensible.js" },
{ "name": "sensible.img", "url": "sensible-icon.js", "evaluate": true }
]
"id": "sensible",
"name": "SensiBLE",
"shortName": "SensiBLE",
"version": "0.06",
"description": "Collect, display and advertise real-time sensor data.",
"icon": "sensible.png",
"screenshots": [
{ "url": "screenshot-top.png" },
{ "url": "screenshot-acc.png" },
{ "url": "screenshot-bar.png" },
{ "url": "screenshot-gps.png" },
{ "url": "screenshot-hrm.png" },
{ "url": "screenshot-mag.png" }
],
"type": "app",
"tags": "tool,sensors,bluetooth",
"supports" : [ "BANGLEJS2" ],
"allow_emulator": true,
"readme": "README.md",
"storage": [
{ "name": "sensible.app.js", "url": "sensible.js" },
{ "name": "sensible.img", "url": "sensible-icon.js", "evaluate": true }
],
"data": [
{ "name": "sensible.data.json", "url": "settings.json", "storageFile": true }
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -1,5 +1,5 @@
/**
* Copyright reelyActive 2021
* Copyright reelyActive 2021-2022
* We believe in an open Internet of Things
*/
@ -7,6 +7,8 @@
// Non-user-configurable constants
const APP_ID = 'sensible';
const ESPRUINO_COMPANY_CODE = 0x0590;
const SETTINGS_FILENAME = 'sensible.data.json';
const UPDATE_MILLISECONDS = 1000;
const APP_ADVERTISING_DATA = [ 0x12, 0xff, 0x90, 0x05, 0x7b, 0x6e, 0x61, 0x6d,
0x65, 0x3a, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x62,
0x6c, 0x65, 0x7d ];
@ -19,16 +21,12 @@ let isBarMenu = false;
let isGpsMenu = false;
let isHrmMenu = false;
let isMagMenu = false;
let isBarEnabled = true;
let isGpsEnabled = true;
let isHrmEnabled = true;
let isMagEnabled = true;
let isNewAccData = false;
let isNewBarData = false;
let isNewGpsData = false;
let isNewHrmData = false;
let isNewMagData = false;
let settings = require('Storage').readJSON(SETTINGS_FILENAME);
// Menus
@ -51,9 +49,9 @@ let accMenu = {
let barMenu = {
"": { "title" : "- Barometer -" },
"State": {
value: isBarEnabled,
value: settings.isBarEnabled,
format: v => v ? "On" : "Off",
onchange: v => { isBarEnabled = v; Bangle.setBarometerPower(v, APP_ID); }
onchange: v => { updateSetting('isBarEnabled', v); }
},
"Altitude": { value: null },
"Press": { value: null },
@ -63,9 +61,9 @@ let barMenu = {
let gpsMenu = {
"": { "title" : "- GPS -" },
"State": {
value: isGpsEnabled,
value: settings.isGpsEnabled,
format: v => v ? "On" : "Off",
onchange: v => { isGpsEnabled = v; Bangle.setGPSPower(v, APP_ID); }
onchange: v => { updateSetting('isGpsEnabled', v); }
},
"Lat": { value: null },
"Lon": { value: null },
@ -77,9 +75,9 @@ let gpsMenu = {
let hrmMenu = {
"": { "title" : "- Heart Rate -" },
"State": {
value: isHrmEnabled,
value: settings.isHrmEnabled,
format: v => v ? "On" : "Off",
onchange: v => { isHrmEnabled = v; Bangle.setHRMPower(v, APP_ID); }
onchange: v => { updateSetting('isHrmEnabled', v); }
},
"BPM": { value: null },
"Confidence": { value: null },
@ -88,9 +86,9 @@ let hrmMenu = {
let magMenu = {
"": { "title" : "- Magnetometer -" },
"State": {
value: isMagEnabled,
value: settings.isMagEnabled,
format: v => v ? "On" : "Off",
onchange: v => { isMagEnabled = v; Bangle.setCompassPower(v, APP_ID); }
onchange: v => { updateSetting('isMagEnabled', v); }
},
"x": { value: null },
"y": { value: null },
@ -124,7 +122,7 @@ function transmitUpdatedSensorData() {
isNewMagData = false;
}
let interval = 1000 / data.length;
let interval = UPDATE_MILLISECONDS / data.length;
NRF.setAdvertising(data, { showName: false, interval: interval });
}
@ -190,6 +188,23 @@ function toByteArray(value, numberOfBytes, isSigned) {
}
// Enable the sensors as per the current settings
function enableSensors() {
Bangle.setBarometerPower(settings.isBarEnabled, APP_ID);
Bangle.setGPSPower(settings.isGpsEnabled, APP_ID);
Bangle.setHRMPower(settings.isHrmEnabled, APP_ID);
Bangle.setCompassPower(settings.isMagEnabled, APP_ID);
}
// Update the given setting and write to persistent storage
function updateSetting(name, value) {
settings[name] = value;
require('Storage').writeJSON(SETTINGS_FILENAME, settings);
enableSensors();
}
// Update acceleration
Bangle.on('accel', function(newAcc) {
acc = newAcc;
@ -260,9 +275,6 @@ Bangle.on('mag', function(newMag) {
// On start: enable sensors and display main menu
g.clear();
Bangle.setBarometerPower(isBarEnabled, APP_ID);
Bangle.setGPSPower(isGpsEnabled, APP_ID);
Bangle.setHRMPower(isHrmEnabled, APP_ID);
Bangle.setCompassPower(isMagEnabled, APP_ID);
enableSensors();
E.showMenu(mainMenu);
setInterval(transmitUpdatedSensorData, 1000);
setInterval(transmitUpdatedSensorData, UPDATE_MILLISECONDS);

View File

@ -0,0 +1,6 @@
{
"isBarEnabled": false,
"isGpsEnabled": false,
"isHrmEnabled": false,
"isMagEnabled": false
}

View File

@ -1,2 +1,3 @@
0.01: New App!
0.02: Respect Quiet Mode
0.03: Add compatibility for Bangle.js 2 and new firmware, added "Alarm at " for the alarm time

View File

@ -1,3 +1,4 @@
const BANGLEJS2 = process.env.HWVERSION == 2; //# check for bangle 2
const alarms = require("Storage").readJSON("alarm.json",1)||[];
const active = alarms.filter(a=>a.on);
@ -52,21 +53,21 @@ active.forEach(alarm => {
}
});
function drawString(s, x, y) {
g.clearRect(0,y-15,239,y+15);
g.reset();
g.setFont("Vector",20);
g.setFontAlign(0,0); // align right bottom
g.drawString(s, x, y);
function drawString(s, y) { //# replaced x: always centered
g.reset(); //# moved up to prevent blue background
g.clearRect(0, y - 12, 239, y + 8); //# minimized upper+lower clearing
g.setFont("Vector", 20);
g.setFontAlign(0, 0); // align centered
g.drawString(s, g.getWidth() / 2, y); //# set x to center
}
function drawApp() {
g.clearRect(0,24,239,215);
g.clearRect(0,24,239,215); //# no problem
var alarmHour = nextAlarm.getHours();
var alarmMinute = nextAlarm.getMinutes();
if (alarmHour < 10) alarmHour = "0" + alarmHour;
if (alarmMinute < 10) alarmMinute = "0" + alarmMinute;
const s = alarmHour + ":" + alarmMinute + "\n\n";
const s = "Alarm at " + alarmHour + ":" + alarmMinute + "\n\n"; //# make distinct to time
E.showMessage(s, "Sleep Phase Alarm");
function drawTime() {
@ -78,12 +79,20 @@ function drawApp() {
if (nowHour < 10) nowHour = "0" + nowHour;
if (nowMinute < 10) nowMinute = "0" + nowMinute;
if (nowSecond < 10) nowSecond = "0" + nowSecond;
const time = nowHour + ":" + nowMinute + ":" + nowSecond;
drawString(time, 120, 140);
const time = nowHour + ":" + nowMinute + (BANGLEJS2 ? "" : ":" + nowSecond); //# hide seconds on bangle 2
drawString(time, BANGLEJS2 ? 85 : 105); //# remove x, adjust height for bangle 2 an newer firmware
}
}
setInterval(drawTime, 500); // 2Hz
if (BANGLEJS2) {
drawTime();
setTimeout(_ => {
drawTime();
setInterval(drawTime, 60000);
}, 60000 - Date.now() % 60000); //# every new minute on bangle 2
} else {
setInterval(drawTime, 500); // 2Hz
}
}
var buzzCount = 19;
@ -104,8 +113,8 @@ function buzz() {
var minAlarm = new Date();
var measure = true;
if (nextAlarm !== undefined) {
Bangle.loadWidgets(); //# correct widget load draw order
Bangle.drawWidgets();
Bangle.loadWidgets();
// minimum alert 30 minutes early
minAlarm.setTime(nextAlarm.getTime() - (30*60*1000));
@ -116,7 +125,7 @@ if (nextAlarm !== undefined) {
if (swest !== undefined) {
if (Bangle.isLCDOn()) {
drawString(swest ? "Sleep" : "Awake", 120, 180);
drawString(swest ? "Sleep" : "Awake", BANGLEJS2 ? 150 : 180); //# remove x, adjust height
}
}
@ -133,6 +142,6 @@ if (nextAlarm !== undefined) {
E.showMessage('No Alarm');
setTimeout(load, 1000);
}
// BTN2 to menu, BTN3 to main
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
setWatch(() => load(), BTN3, { repeat: false, edge: "falling" });
// BTN2 to menu, BTN3 to main # on bangle 2 only BTN to main
if (!BANGLEJS2) setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
setWatch(() => load(), BANGLEJS2 ? BTN : BTN3, { repeat: false, edge: "falling" });

View File

@ -2,11 +2,11 @@
"id": "sleepphasealarm",
"name": "SleepPhaseAlarm",
"shortName": "SleepPhaseAlarm",
"version": "0.02",
"version": "0.03",
"description": "Uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS, see https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en). This app will read the next alarm from the alarm application and will wake you up to 30 minutes early at the best guessed time when you are almost already awake.",
"icon": "app.png",
"tags": "alarm",
"supports": ["BANGLEJS"],
"supports": ["BANGLEJS","BANGLEJS2"],
"storage": [
{"name":"sleepphasealarm.app.js","url":"app.js"},
{"name":"sleepphasealarm.img","url":"app-icon.js","evaluate":true}