mirror of https://github.com/espruino/BangleApps
Added app for reading from bluetooth plan moisture sensors
parent
4391b48aeb
commit
b7ef9e424c
12
apps.json
12
apps.json
|
@ -1615,6 +1615,18 @@
|
||||||
{"name":"switch-off.img","url":"switch-off.js","evaluate":true}
|
{"name":"switch-off.img","url":"switch-off.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{ "id": "miplant",
|
||||||
|
"name": "Xiaomi Plant Sensor",
|
||||||
|
"shortName":"Mi Plant",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Reads and displays data from Xiaomi bluetooth plant moisture sensors",
|
||||||
|
"tags": "xiaomi,mi,plant,ble,bluetooth",
|
||||||
|
"storage": [
|
||||||
|
{"name":"miplant.app.js","url":"app.js"},
|
||||||
|
{"name":"miplant.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "simpletimer",
|
"id": "simpletimer",
|
||||||
"name": "Timer",
|
"name": "Timer",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwxH+4AA/AH4A/AAPQ64AQ44ZKBYwvc6/QF9wwFF9XXF73I4IAH44/F54vdCpYQESAYvm5Avm44ADA4Yvmc44v/F/4v/F/4v/F/4v+zmjv4ABF9GrwoACrYvn2WGFwgABSh4AV0QtDFwYvmFwlhF9wuDF9QuEF82jFw4vmMIQuFv4vuEDOi0d/WgV/0YNGBIN/LrSvCABAkECAI4GAChKBF5QABCIYEDADKpCsIvJLQQ0EGoShJMBwACSJYvEB5GiMCYxJF4LuCLorTLF6IxGQILuBMYgAGC4QwP0YwHYwQbCF4K1CL4lhCohfQMBBiCFQQvEAgIsFAATxWSQyPDAYYSIHgRgZE4IsBF4QGCCI6NRMBboFXgTTIFyYwIPYWcGAb2CCI2iF6qwBD4aqERYQABIQ+cFywALLwgAqXoYvrSAQROA=="))
|
|
@ -0,0 +1,74 @@
|
||||||
|
|
||||||
|
function getImgHum() {
|
||||||
|
return require("heatshrink").decompress(atob("jUoxH+AEtlsoYYDS4ZYDAYaVDLAYFDSQYHDSIZYDBIaPDLAYLDRoZYDBoaLDLAYPDRIZYDCIaHDLAYTDQoZYDCoaDDOQYXAA+JxIYX1utDSwYBAAIzYGiwZUTgpODQpzPGGgY3OdI4aRDIIaMDJIYCDIztDGRwaJP5oaWDAwaRDBAbOC5YcKB5I="));
|
||||||
|
}
|
||||||
|
function getImgTemp() {
|
||||||
|
return require("heatshrink").decompress(atob("iUqxH+AA2sAAQLHCBASMCAoSLCPOBAAQRfI/5Hn3YACy4ACCL4ADCL5H/I/AQHCRAQJCQwQLCQgQNCQYRQCB4A/ADaPjYqTpSCRYQGCZALFA"));
|
||||||
|
}
|
||||||
|
function getImgFert() {
|
||||||
|
return require("heatshrink").decompress(atob("kklxH+AC+FwtbDbAfFAAVbEbgiGEbYiHEbQiEsIjiEQYjeEQiPdEQrXdEdKnTAAJsMD6QlJFZAAIGAIkPEaIkCrdhEaR9MT4gkLFAyjMYoojNUZ4jFEoxrGEBCJDEZSWEEZdhCwpsKJQiJFAgYgGEQwjLD4QjFCRD+KCAylGQ4gjXVhAiPEhAKDJIwiQEowIEEQo2GERgAKEYwAcEUQkDEL9VAAgHFETgAIDJwePEZwdTE5ggdMJt6AAQEEqwRMABYQDAAwkBF5AkKEBQAPEUR6ESAQicJIX+A=="));
|
||||||
|
}
|
||||||
|
|
||||||
|
var deviceInfo = {};
|
||||||
|
|
||||||
|
function parseDevice(device) {
|
||||||
|
var d = new DataView(device.serviceData["fe95"]);
|
||||||
|
var frame = d.getUint16(0,true);
|
||||||
|
var offset = 5;
|
||||||
|
if (frame&16) offset+=6; // mac address
|
||||||
|
if (frame&32) offset+=1; // capabilitities
|
||||||
|
if (frame&64) { // event
|
||||||
|
var l = d.getUint8(offset+2);
|
||||||
|
var code = d.getUint16(offset,true);
|
||||||
|
if (!deviceInfo[device.id]) deviceInfo[device.id]={id:device.id};
|
||||||
|
event = deviceInfo[device.id];
|
||||||
|
switch (code) {
|
||||||
|
case 0x1004: event.temperature = d.getInt16(offset+3,true)/10; break;
|
||||||
|
case 0x1006: event.humidity = d.getInt16(offset+3)/10; break;
|
||||||
|
case 0x100D:
|
||||||
|
event.temperature = d.getInt16(offset+3,true)/10;
|
||||||
|
event.humidity = d.getInt16(offset+5)/10; break;
|
||||||
|
case 0x1008: event.moisture = d.getUint8(offset+3); break;
|
||||||
|
case 0x1009: event.fertility = d.getUint16(offset+3,true)/10; break;
|
||||||
|
// case 0x1007: break; // 3 bytes? got 84,0,0 or 68,0,0
|
||||||
|
default: event.code = code;
|
||||||
|
event.raw = new Uint8Array(d.buffer, offset+3, l);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//print(event);
|
||||||
|
show(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
eg. {
|
||||||
|
"id": "c4:7c:8d:6a:ac:79 public",
|
||||||
|
"temperature": 16.6, "code": 4103,
|
||||||
|
"raw": new Uint8Array([246, 0, 0]),
|
||||||
|
"moisture": 46, "fertility": 20.8 }
|
||||||
|
*/
|
||||||
|
function show(event) {
|
||||||
|
g.reset().setFont("6x8");
|
||||||
|
var y = 45 + 50*Object.keys(deviceInfo).indexOf(event.id);
|
||||||
|
|
||||||
|
g.drawString(event.id.substr(0,17),0,y);
|
||||||
|
g.drawImage(getImgHum(),0,y+15);
|
||||||
|
g.setFont("6x8",2);
|
||||||
|
var t = (event.moisture===undefined) ? "?" : event.moisture;
|
||||||
|
g.drawString((t+" ").substr(0,3),35,y+25,true);
|
||||||
|
g.drawImage(getImgFert(),80,y+15);
|
||||||
|
t = Math.round(event.fertility) || "?";
|
||||||
|
g.drawString((t+" ").substr(0,3), 120, y+25, true);
|
||||||
|
g.drawImage(getImgTemp(),160,y+15);
|
||||||
|
t = Math.round(event.temperature) || "?";
|
||||||
|
g.drawString((t+" ").substr(0,3), 180, y+25, true);
|
||||||
|
g.flip();
|
||||||
|
}
|
||||||
|
|
||||||
|
g.clear();
|
||||||
|
g.setFont("6x8",2).setFontAlign(0,-1).drawString("Scanning...",120,24);
|
||||||
|
|
||||||
|
Bangle.loadWidgets()
|
||||||
|
Bangle.drawWidgets()
|
||||||
|
|
||||||
|
NRF.setScan(parseDevice, { filters: [{serviceData:{"fe95":{}}}], timeout: 2000 });
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Loading…
Reference in New Issue