openvibers/openvibe.bot Commits
LOOI battery: a fresh poll is not provisional; unverified means a read at connect or a stale value (#428)
Changes
@@@ -1443,8 +1443,10 @@pill.dataset.state = dataState;}// Battery | Latency. A missing reading is a dash, an empty bar and the word unknown, never 0 %; a voltage is-- // never invented. The tray's reading says how fresh it is: "read at connect" for an unverified FED8 read, or-- // "updated 12s ago" from its `at`. No `at` and not unverified: no note.++ // never invented. The tray's reading says how fresh it is (Maticus's P7 list, 2026-11-12): a fresh poll is++ // { pct, usb, raw, at } with no `unverified`, shown as "updated 12s ago"; `unverified` comes only with a read at++ // connect or a stale value, shown as "provisional" with its age ("provisional, from 3m ago", or "provisional, read++ // at connect" when the tray says so). No `at` and not unverified: no note.function batteryAge(at) {const then = typeof at === 'number' ? at : Date.parse(at);if (!Number.isFinite(then)) return '';@@@ -1474,10 +1476,12 @@const p7 = sensors && sensors.p7_battery && typeof sensors.p7_battery === 'object' ? sensors.p7_battery : null;let freshness = '';if (fraction != null && p7) {-- // The tray polls it now (source 'poll'): still provisional, but as fresh as its `at` (Maticus, 2026-11-12).-- if (p7.source === 'poll' && p7.at != null) { const age = batteryAge(p7.at); freshness = age ? `provisional, updated ${age} ago` : 'provisional'; }-- else if (p7.unverified === true) freshness = 'read at connect';-- else if (p7.at != null) {++ if (p7.unverified === true) {++ // A minute old or less is the read at connect; older is a value gone stale.++ const then = p7.at == null ? NaN : (typeof p7.at === 'number' ? p7.at : Date.parse(p7.at));++ const stale = Number.isFinite(then) && Date.now() - then > 60000 && p7.source !== 'connect';++ freshness = stale ? `provisional, from ${batteryAge(p7.at)} ago` : 'provisional, read at connect';++ } else if (p7.at != null) {const age = batteryAge(p7.at);if (age) freshness = `updated ${age} ago`;}@@@ -84,12 +84,12 @@ function panelPage() {}(async () => {-- await check('the battery row says read at connect, updated Ns/min ago, or nothing; a missing reading is a dash and unknown', () => {++ await check('the battery row says provisional at connect, updated Ns/min ago, or nothing; a missing reading is a dash and unknown', () => {const page = panelPage();page.state({ battery: 0.42, telemetry: { sensors: { p7_battery: { pct: 42, unverified: true, at: iso(NOW - 500) } } } });assert.strictEqual(page.batteryText.textContent, '42 %');assert.strictEqual(page.batteryNote.hidden, true);-- assert.strictEqual(page.batteryFreshness.textContent, 'read at connect');++ assert.strictEqual(page.batteryFreshness.textContent, 'provisional, read at connect');assert.strictEqual(page.batteryFreshness.hidden, false);page.state({ battery: 0.42, telemetry: { sensors: { p7_battery: { pct: 42, at: iso(NOW - 12300) } } } });assert.strictEqual(page.batteryFreshness.textContent, 'updated 12s ago');@@@ -106,14 +106,16 @@ function panelPage() {assert.strictEqual(page.batteryFreshness.hidden, true, 'a missing reading has no freshness note');});-- await check('a polled reading says provisional, updated Ns ago (source poll, Maticus 11-12)', () => {++ await check('a fresh poll is not provisional; unverified (at connect or stale) is (Maticus\'s P7 list, 11-12)', () => {const page = panelPage();-- page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, usb: false, raw: 153, unverified: true, source: 'poll', at: iso(NOW - 7400) } } } });-- assert.strictEqual(page.batteryFreshness.textContent, 'provisional, updated 7s ago');-- page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true, source: 'poll', at: NOW - 180000 } } } });-- assert.strictEqual(page.batteryFreshness.textContent, 'provisional, updated 3m ago');-- page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true, at: iso(NOW - 500) } } } });-- assert.strictEqual(page.batteryFreshness.textContent, 'read at connect', 'a read at connect still says so');++ page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, usb: false, raw: 153, at: NOW - 7400 } } } });++ assert.strictEqual(page.batteryFreshness.textContent, 'updated 7s ago', 'a fresh poll: { pct, usb, raw, at }, no unverified');++ page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true, at: NOW - 180000 } } } });++ assert.strictEqual(page.batteryFreshness.textContent, 'provisional, from 3m ago', 'a stale value');++ page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true, source: 'connect', at: iso(NOW - 500) } } } });++ assert.strictEqual(page.batteryFreshness.textContent, 'provisional, read at connect');++ page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true } } } });++ assert.strictEqual(page.batteryFreshness.textContent, 'provisional, read at connect', 'unverified with no time: a read at connect');});await check('the head slider names its mounting: Portrait and its range, or Landscape; nothing without p7_head', () => {
@@ -1443,8 +1443,10 @@
@@ -1443,8 +1443,10 @@
pill.dataset.state = dataState;
pill.dataset.state = dataState;
}
}
// Battery | Latency. A missing reading is a dash, an empty bar and the word unknown, never 0 %; a voltage is
// Battery | Latency. A missing reading is a dash, an empty bar and the word unknown, never 0 %; a voltage is
- // never invented. The tray's reading says how fresh it is: "read at connect" for an unverified FED8 read, or
- // "updated 12s ago" from its `at`. No `at` and not unverified: no note.
+ // never invented. The tray's reading says how fresh it is (Maticus's P7 list, 2026-11-12): a fresh poll is
+ // { pct, usb, raw, at } with no `unverified`, shown as "updated 12s ago"; `unverified` comes only with a read at
+ // connect or a stale value, shown as "provisional" with its age ("provisional, from 3m ago", or "provisional, read
+ // at connect" when the tray says so). No `at` and not unverified: no note.
function batteryAge(at) {
function batteryAge(at) {
const then = typeof at === 'number' ? at : Date.parse(at);
const then = typeof at === 'number' ? at : Date.parse(at);
if (!Number.isFinite(then)) return '';
if (!Number.isFinite(then)) return '';
@@ -1474,10 +1476,12 @@
@@ -1474,10 +1476,12 @@
const p7 = sensors && sensors.p7_battery && typeof sensors.p7_battery === 'object' ? sensors.p7_battery : null;
const p7 = sensors && sensors.p7_battery && typeof sensors.p7_battery === 'object' ? sensors.p7_battery : null;
let freshness = '';
let freshness = '';
if (fraction != null && p7) {
if (fraction != null && p7) {
- // The tray polls it now (source 'poll'): still provisional, but as fresh as its `at` (Maticus, 2026-11-12).
- if (p7.source === 'poll' && p7.at != null) { const age = batteryAge(p7.at); freshness = age ? `provisional, updated ${age} ago` : 'provisional'; }
- else if (p7.unverified === true) freshness = 'read at connect';
- else if (p7.at != null) {
+ if (p7.unverified === true) {
+ // A minute old or less is the read at connect; older is a value gone stale.
+ const then = p7.at == null ? NaN : (typeof p7.at === 'number' ? p7.at : Date.parse(p7.at));
+ const stale = Number.isFinite(then) && Date.now() - then > 60000 && p7.source !== 'connect';
+ freshness = stale ? `provisional, from ${batteryAge(p7.at)} ago` : 'provisional, read at connect';
+ } else if (p7.at != null) {
const age = batteryAge(p7.at);
const age = batteryAge(p7.at);
if (age) freshness = `updated ${age} ago`;
if (age) freshness = `updated ${age} ago`;
}
}
@@ -84,12 +84,12 @@ function panelPage() {
@@ -84,12 +84,12 @@ function panelPage() {
}
}
(async () => {
(async () => {
- await check('the battery row says read at connect, updated Ns/min ago, or nothing; a missing reading is a dash and unknown', () => {
+ await check('the battery row says provisional at connect, updated Ns/min ago, or nothing; a missing reading is a dash and unknown', () => {
const page = panelPage();
const page = panelPage();
page.state({ battery: 0.42, telemetry: { sensors: { p7_battery: { pct: 42, unverified: true, at: iso(NOW - 500) } } } });
page.state({ battery: 0.42, telemetry: { sensors: { p7_battery: { pct: 42, unverified: true, at: iso(NOW - 500) } } } });
assert.strictEqual(page.batteryText.textContent, '42 %');
assert.strictEqual(page.batteryText.textContent, '42 %');
assert.strictEqual(page.batteryNote.hidden, true);
assert.strictEqual(page.batteryNote.hidden, true);
- assert.strictEqual(page.batteryFreshness.textContent, 'read at connect');
+ assert.strictEqual(page.batteryFreshness.textContent, 'provisional, read at connect');
assert.strictEqual(page.batteryFreshness.hidden, false);
assert.strictEqual(page.batteryFreshness.hidden, false);
page.state({ battery: 0.42, telemetry: { sensors: { p7_battery: { pct: 42, at: iso(NOW - 12300) } } } });
page.state({ battery: 0.42, telemetry: { sensors: { p7_battery: { pct: 42, at: iso(NOW - 12300) } } } });
assert.strictEqual(page.batteryFreshness.textContent, 'updated 12s ago');
assert.strictEqual(page.batteryFreshness.textContent, 'updated 12s ago');
@@ -106,14 +106,16 @@ function panelPage() {
@@ -106,14 +106,16 @@ function panelPage() {
assert.strictEqual(page.batteryFreshness.hidden, true, 'a missing reading has no freshness note');
assert.strictEqual(page.batteryFreshness.hidden, true, 'a missing reading has no freshness note');
});
});
- await check('a polled reading says provisional, updated Ns ago (source poll, Maticus 11-12)', () => {
+ await check('a fresh poll is not provisional; unverified (at connect or stale) is (Maticus\'s P7 list, 11-12)', () => {
const page = panelPage();
const page = panelPage();
- page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, usb: false, raw: 153, unverified: true, source: 'poll', at: iso(NOW - 7400) } } } });
- assert.strictEqual(page.batteryFreshness.textContent, 'provisional, updated 7s ago');
- page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true, source: 'poll', at: NOW - 180000 } } } });
- assert.strictEqual(page.batteryFreshness.textContent, 'provisional, updated 3m ago');
- page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true, at: iso(NOW - 500) } } } });
- assert.strictEqual(page.batteryFreshness.textContent, 'read at connect', 'a read at connect still says so');
+ page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, usb: false, raw: 153, at: NOW - 7400 } } } });
+ assert.strictEqual(page.batteryFreshness.textContent, 'updated 7s ago', 'a fresh poll: { pct, usb, raw, at }, no unverified');
+ page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true, at: NOW - 180000 } } } });
+ assert.strictEqual(page.batteryFreshness.textContent, 'provisional, from 3m ago', 'a stale value');
+ page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true, source: 'connect', at: iso(NOW - 500) } } } });
+ assert.strictEqual(page.batteryFreshness.textContent, 'provisional, read at connect');
+ page.state({ battery: 0.6, telemetry: { sensors: { p7_battery: { pct: 60, unverified: true } } } });
+ assert.strictEqual(page.batteryFreshness.textContent, 'provisional, read at connect', 'unverified with no time: a read at connect');
});
});
await check('the head slider names its mounting: Portrait and its range, or Landscape; nothing without p7_head', () => {
await check('the head slider names its mounting: Portrait and its range, or Landscape; nothing without p7_head', () => {