SwitchBot温湿度計
高くて2000円、セールなら1000円ぐらいで買えるこれ
https://qiita.com/takeru@github/items/f42381e8482c3bf484e7
BLEで温度湿度を取れるので、Obnizでも温度湿度を取れるようにしました。
ObnizはBLEとWebにつなぐのが得意なので、BLEでデータ取得+ブラウザに表示します。
部品
- obniz Board 1Y https://amzn.to/2Ss7iBt
- SwitchBot温湿度計 https://amzn.to/3tyvwaf
ソースコード
SwitchBot温湿度計
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" />
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/obniz@3.x/obniz.js" crossorigin="anonymous" ></script>
<style>
@font-face {
font-family: "DESG";
src: url("data:application/font-woff; charset=utf-8; base64,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") format("woff2");
// Font "DSEG" by けしかん
}
.meter { display: inline-block; }
.outer { border: black solid 3px; border-radius: 15px; width: 300px; height: 300px; padding: 40px; margin: 20px; background-color: aliceblue; }
.inner .temperature { margin: 0 0 0 30px; }
.inner .humidity { margin: 0 0 0 30px; }
.inner .address { font-size: 6px; }
.inner { border: black solid 3px; border-radius: 5px; height: 100%; background-color: darkseagreen; font-family: "DESG"; font-size: 60px; };
</style>
</head>
<body>
<div id="obniz-debug"></div>
<h4></h4>
<div id="meters">
<div id="template" class="meter" style="display:none;">
<div class="outer">
<div class="inner">
<div class="temperature">12.3</div>
<div class="line"></div>
<div class="humidity">45</div>
<span class="address">xxxx</span>
</div>
</div>
</div>
</div>
<script>
const obniz = new Obniz("OBNIZ_ID_HERE");
const known_meters = {
"d6091889b956": "Meter02",
"fffbc4aa4ff5": "Meter03",
"ee33dc9c7261": "Meter01"
};
const log = (s)=>{
console.log((new Date()).toISOString()+" "+s);
};
const status = (s)=>{
$('h4').html(s);
log(s);
};
const data = {};
const onfind_meter = function(peripheral){
const find_servicedata = () => peripheral.advertise_data_rows.find(r => r[0]==22 && r[1]==0 && r[2]==13);
let servicedata = find_servicedata();
if(servicedata){
servicedata = servicedata.slice(3);
const battery = servicedata[2] & 0b01111111;
const isTemperatureAboveFreezing = servicedata[4] & 0b10000000;
let temperature = ( servicedata[3] & 0b00001111 ) / 10.0 + ( servicedata[4] & 0b01111111 );
if(!isTemperatureAboveFreezing){
temperature = -temperature;
}
const humidity = servicedata[5] & 0b01111111;
const isEncrypted = ( servicedata[0] & 0b10000000 ) >> 7;
const isDualStateMode = ( servicedata[1] & 0b10000000 ) >> 7;
const isStatusOff = ( servicedata[1] & 0b01000000 ) >> 6;
const isTemperatureHighAlert = ( servicedata[3] & 0b10000000 ) >> 7;
const isTemperatureLowAlert = ( servicedata[3] & 0b01000000 ) >> 6;
const isHumidityHighAlert = ( servicedata[3] & 0b00100000 ) >> 5;
const isHumidityLowAlert = ( servicedata[3] & 0b00010000 ) >> 4;
const isTemperatureUnitF = ( servicedata[5] & 0b10000000 ) >> 7;
log(peripheral.address+" "+battery+" "+temperature+" "+humidity);
data[peripheral.address] = {"a": peripheral.address, "t": temperature, "h": humidity, "b": battery};
if (!Obniz.App.isCloudRunning()) {
updateUI();
}
/*
console.log("----\n");
console.log("address: %s\n", peripheral.address);
console.log("battery: %d\n", battery);
console.log("temperature: %.1f\n", temperature);
console.log("humidity: %d\n", humidity);
console.log("\n");
console.log("isEncrypted: %d\n", isEncrypted);
console.log("isDualStateMode: %d\n", isDualStateMode);
console.log("isStatusOff: %d\n", isStatusOff);
console.log("isTemperatureHighAlert: %d\n", isTemperatureHighAlert);
console.log("isTemperatureLowAlert: %d\n", isTemperatureLowAlert);
console.log("isHumidityHighAlert: %d\n", isHumidityHighAlert);
console.log("isHumidityLowAlert: %d\n", isHumidityLowAlert);
console.log("isTemperatureUnitF: %d\n", isTemperatureUnitF);
console.log("----\n");
*/
}
};
const scan_meter = async function(){
let target = null;
// target = {"deviceAddress":[
// "d6091889b956", // Meter02
// "fffbc4aa4ff5", // Meter03
// ]};
let scanSeconds;
if (Obniz.App.isCloudRunning()) {
scanSeconds = 20;
}else{
scanSeconds = null;
}
const setting = {
duration: scanSeconds,
duplicate: true,
filterOnDevice: false
};
status("Scanning");
const peripherals = await obniz.ble.scan.startAllWait(target, setting);
//var peripherals = [await obniz.ble.scan.startOneWait(target, setting)];
status("Finished");
};
function uniq(array) {
return [...new Set(array)];
}
const updateUI = ()=>{
keys = uniq([...Object.keys(known_meters), ...Object.keys(data)]);
keys.forEach((k)=>{
const d = data[k] || {"a": k, "t": "--", "h": "--"};
console.log(k + " " + JSON.stringify(d));
let m = $("#meters #address-"+k);
if(m.length==0){
let e = $("#meters #template").clone().attr("id", "address-"+k);
$("#meters").append(e);
e.show();
m = $("#meters #address-"+k);
}
$(".address", m).html(d["a"]);
$(".temperature", m).html(d["t"]);
$(".humidity", m).html(d["h"]);
});
};
obniz.onconnect = async function() {
status("Obniz Connected");
await obniz.ble.initWait();
status("Init");
obniz.ble.scan.onfind = onfind_meter;
updateUI();
}
obniz.onloop = async function() {
status("Loop");
await scan_meter();
if (Obniz.App.isCloudRunning()) {
Obniz.App.done({
status: 'success',
text: JSON.stringify(data)
})
}
//status("Wait");
//await obniz.wait(10 * 1000);
};
</script>
</body>
</html>
-
takeru
さんが
2021/05/09
に
編集
をしました。
(メッセージ: 初版)
-
takeru
さんが
2021/05/09
に
編集
をしました。
-
takeru
さんが
2021/05/09
に
編集
をしました。
-
takeru
さんが
2021/05/10
に
編集
をしました。
-
takeru
さんが
2021/12/22
に
編集
をしました。
ログインしてコメントを投稿する