forked from FOSS/BangleApps
173 lines
3.9 KiB
JavaScript
173 lines
3.9 KiB
JavaScript
var filterTemperature = [{
|
|
serviceData: {
|
|
"181a": {}
|
|
}
|
|
}];
|
|
var results = {};
|
|
var macs = [];
|
|
|
|
var aliases = require("Storage").readJSON("mitherm.json", true);
|
|
if (!aliases) aliases = {};
|
|
|
|
var lastSeen = {};
|
|
var current = 0;
|
|
var scanning = false;
|
|
var timeoutDraw;
|
|
var timeoutScan;
|
|
|
|
|
|
const scan = function() {
|
|
if (!scanning) { // Don't start scanning if already doing so.
|
|
scanning = true;
|
|
if (timeoutScan) clearTimeout(timeoutScan);
|
|
timeoutScan = setTimeout(scan, 300000); // Scan again in 5 minutes.
|
|
drawScanState(scanning);
|
|
NRF.findDevices(function(devices) {
|
|
onDevices(devices);
|
|
}, {
|
|
filters: filterTemperature,
|
|
timeout: 30000 // Scan for 30s
|
|
});
|
|
}
|
|
};
|
|
|
|
|
|
const onDevices = function(devices) {
|
|
let now = Date.now();
|
|
for (let i = 0; i < devices.length; i++) {
|
|
let device = devices[i];
|
|
|
|
let processedData = extractData(device.data);
|
|
console.log({
|
|
rssi: device.rssi,
|
|
data: processedData
|
|
});
|
|
if (!macs.includes(processedData.MAC)) {
|
|
macs.push(processedData.MAC);
|
|
}
|
|
results[processedData.MAC] = processedData;
|
|
lastSeen[processedData.MAC] = now;
|
|
}
|
|
console.log("Scan complete.");
|
|
scanning = false;
|
|
writeOutput();
|
|
};
|
|
|
|
|
|
const extractData = function(thedata) {
|
|
let data = DataView(thedata);
|
|
let MAC = [];
|
|
for (let i = 9; i > 3; i--) {
|
|
MAC.push(data.getUint8(i, true).toString(16).padStart(2, "0"));
|
|
}
|
|
out = {
|
|
size: data.getUint8(0, true),
|
|
uid: data.getUint8(1, true),
|
|
UUID: data.getUint16(2, true),
|
|
MAC: MAC.join(":"),
|
|
temperature: data.getInt16(10, true) * 0.01,
|
|
humidity: data.getUint16(12, true) * 0.01,
|
|
battery_mv: data.getUint16(14, true),
|
|
battery_level: data.getUint8(16, true),
|
|
};
|
|
return out;
|
|
};
|
|
|
|
|
|
const writeOutput = function() {
|
|
let now = Date.now();
|
|
if (timeoutDraw) clearTimeout(timeoutDraw);
|
|
timeoutDraw = setTimeout(writeOutput, 60000); // Refresh in 1 minute.
|
|
g.clear(true);
|
|
Bangle.drawWidgets();
|
|
g.reset();
|
|
drawScanState(scanning);
|
|
|
|
if (macs.length == 0) return;
|
|
|
|
processedData = results[macs[current]];
|
|
g.setFont12x20(2);
|
|
g.drawString(`${processedData.temperature.toFixed(2)}°C`, 10, 30);
|
|
g.drawString(`${processedData.humidity.toFixed(2)} %`, 10, 70);
|
|
|
|
g.setFont6x15();
|
|
g.drawString(`${((now - lastSeen[macs[current]]) / 60000).toFixed(0)} min ago`, 10, 130);
|
|
g.drawString(`${processedData.battery_level} % battery`, 80, 130);
|
|
g.drawString(` ${processedData.MAC in aliases ? aliases[processedData.MAC] : processedData.MAC}: ${current + 1} / ${macs.length}`, 10, 150);
|
|
};
|
|
|
|
|
|
const scrollDevices = function(directionLR) {
|
|
// Swipe left or right to move between devices.
|
|
current -= directionLR; // inverted feels a more familiar gesture.
|
|
if (current + 1 > macs.length)
|
|
current = 0;
|
|
if (current < 0)
|
|
current = macs.length - 1;
|
|
writeOutput();
|
|
};
|
|
|
|
const drawScanState = function(state) {
|
|
if (state)
|
|
g.fillRect(160, 160, 170, 170);
|
|
else
|
|
g.clearRect(160, 160, 170, 170);
|
|
};
|
|
|
|
const setAlias = function(mac, alias) {
|
|
if (alias === "") {
|
|
delete aliases[mac];
|
|
}
|
|
else {
|
|
aliases[mac] = alias;
|
|
require("Storage").writeJSON("mitherm.json", aliases);
|
|
}
|
|
};
|
|
|
|
const changeAlias = function(mac) {
|
|
g.clear();
|
|
require("textinput").input((mac in aliases) ? aliases[mac] : "").then(function(text) {
|
|
setAlias(mac, text);
|
|
setUI();
|
|
writeOutput();
|
|
});
|
|
};
|
|
|
|
|
|
const setUI = function() {
|
|
Bangle.setUI({
|
|
mode: "custom",
|
|
swipe: scrollDevices,
|
|
btn: function() {
|
|
E.showMenu(actionsMenu);
|
|
}
|
|
});
|
|
};
|
|
|
|
|
|
const actionsMenu = {
|
|
"": {
|
|
"title": "-- Actions --",
|
|
"back": function() {
|
|
E.showMenu();
|
|
},
|
|
"remove": function() {
|
|
setUI();
|
|
writeOutput();
|
|
},
|
|
},
|
|
"Scan now": function() {
|
|
scan();
|
|
E.showMenu();
|
|
},
|
|
"Edit alias": function() {
|
|
changeAlias(macs[current]);
|
|
},
|
|
};
|
|
|
|
setUI();
|
|
Bangle.loadWidgets();
|
|
g.setClipRect(Bangle.appRect);
|
|
scan();
|
|
writeOutput();
|