Shelly skripta
This commit is contained in:
Binary file not shown.
162
shelly/syncscript.js
Normal file
162
shelly/syncscript.js
Normal file
@@ -0,0 +1,162 @@
|
||||
const CONTROLLER_ID="550";
|
||||
|
||||
const senzori = [
|
||||
"7c:c6:b6:74:a4:be",
|
||||
"7c:c6:b6:75:a1:21"
|
||||
];
|
||||
|
||||
const temperature = ["22.0", "22.0"];
|
||||
const humidity = ["50", "50"];
|
||||
|
||||
|
||||
|
||||
let ALLTERCO_MFD_ID_STR = "0ba9";
|
||||
let BTHOME_SVC_ID_STR = "fcd2";
|
||||
|
||||
let ALLTERCO_MFD_ID = JSON.parse("0x" + ALLTERCO_MFD_ID_STR);
|
||||
let BTHOME_SVC_ID = JSON.parse("0x" + BTHOME_SVC_ID_STR);
|
||||
|
||||
let SCAN_DURATION = BLE.Scanner.INFINITE_SCAN;
|
||||
|
||||
let uint8 = 0;
|
||||
let int8 = 1;
|
||||
let uint16 = 2;
|
||||
let int16 = 3;
|
||||
let uint24 = 4;
|
||||
let int24 = 5;
|
||||
|
||||
function getByteSize(type) {
|
||||
if (type === uint8 || type === int8) return 1;
|
||||
if (type === uint16 || type === int16) return 2;
|
||||
if (type === uint24 || type === int24) return 3;
|
||||
//impossible as advertisements are much smaller;
|
||||
return 255;
|
||||
}
|
||||
|
||||
let BTH = [];
|
||||
BTH[0x00] = { n: "pid", t: uint8 };
|
||||
BTH[0x01] = { n: "Battery", t: uint8, u: "%" };
|
||||
BTH[0x3a] = { n: "Button", t: uint8 };
|
||||
BTH[0x2e] = { n: "Humidity", t: uint8 };
|
||||
BTH[0x45] = { n: "Temperature", t: int16, f: 0.1 };
|
||||
|
||||
|
||||
let BTHomeDecoder = {
|
||||
utoi: function (num, bitsz) {
|
||||
let mask = 1 << (bitsz - 1);
|
||||
return num & mask ? num - (1 << bitsz) : num;
|
||||
},
|
||||
getUInt8: function (buffer) {
|
||||
return buffer.at(0);
|
||||
},
|
||||
getInt8: function (buffer) {
|
||||
return this.utoi(this.getUInt8(buffer), 8);
|
||||
},
|
||||
getUInt16LE: function (buffer) {
|
||||
return 0xffff & ((buffer.at(1) << 8) | buffer.at(0));
|
||||
},
|
||||
getInt16LE: function (buffer) {
|
||||
return this.utoi(this.getUInt16LE(buffer), 16);
|
||||
},
|
||||
getUInt24LE: function (buffer) {
|
||||
return (
|
||||
0x00ffffff & ((buffer.at(2) << 16) | (buffer.at(1) << 8) | buffer.at(0))
|
||||
);
|
||||
},
|
||||
getInt24LE: function (buffer) {
|
||||
return this.utoi(this.getUInt24LE(buffer), 24);
|
||||
},
|
||||
getBufValue: function (type, buffer) {
|
||||
if (buffer.length < getByteSize(type)) return null;
|
||||
let res = null;
|
||||
if (type === uint8) res = this.getUInt8(buffer);
|
||||
if (type === int8) res = this.getInt8(buffer);
|
||||
if (type === uint16) res = this.getUInt16LE(buffer);
|
||||
if (type === int16) res = this.getInt16LE(buffer);
|
||||
if (type === uint24) res = this.getUInt24LE(buffer);
|
||||
if (type === int24) res = this.getInt24LE(buffer);
|
||||
return res;
|
||||
},
|
||||
unpack: function (buffer) {
|
||||
// beacons might not provide BTH service data
|
||||
if (typeof buffer !== "string" || buffer.length === 0) return null;
|
||||
let result = {};
|
||||
let _dib = buffer.at(0);
|
||||
result["encryption"] = _dib & 0x1 ? true : false;
|
||||
result["BTHome_version"] = _dib >> 5;
|
||||
if (result["BTHome_version"] !== 2) return null;
|
||||
//Can not handle encrypted data
|
||||
if (result["encryption"]) return result;
|
||||
buffer = buffer.slice(1);
|
||||
|
||||
let _bth;
|
||||
let _value;
|
||||
|
||||
while (buffer.length > 0) {
|
||||
_bth = BTH[buffer.at(0)];
|
||||
if (typeof(_bth) === "undefined") {
|
||||
console.log("BTH: unknown type");
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = buffer.slice(1);
|
||||
_value = this.getBufValue(_bth.t, buffer);
|
||||
|
||||
if (_value === null) break;
|
||||
if (typeof _bth.f !== "undefined") _value = _value * _bth.f;
|
||||
result[_bth.n] = _value;
|
||||
buffer = buffer.slice(getByteSize(_bth.t));
|
||||
}
|
||||
return result;
|
||||
},
|
||||
};
|
||||
|
||||
let ShellyBLUParser = {
|
||||
getData: function (res) {
|
||||
let result = BTHomeDecoder.unpack(res.service_data[BTHOME_SVC_ID_STR]);
|
||||
result.addr = res.addr;
|
||||
result.rssi = res.rssi;
|
||||
return result;
|
||||
},
|
||||
};
|
||||
|
||||
function sendToZoblak() {
|
||||
const url = "http://agrar.zoblak.com/api/v1.0/sensorData";
|
||||
const owner = "Controller: " + CONTROLLER_ID;
|
||||
const payload = {
|
||||
owner: owner,
|
||||
temperatureValue: temperature[0],
|
||||
humidityValue: humidity[0],
|
||||
controllerId: CONTROLLER_ID,
|
||||
temperatures: temperature
|
||||
};
|
||||
|
||||
Shelly.call(
|
||||
"HTTP.POST", {
|
||||
"url": url,
|
||||
"body": JSON.stringify(payload)
|
||||
},
|
||||
function(result) {
|
||||
print("server says: ", result.code);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function handleScanResult(event, result) {
|
||||
if(event === BLE.Scanner.SCAN_RESULT) {
|
||||
for (var i in senzori) {
|
||||
if(result.addr === senzori[i]) {
|
||||
let data = ShellyBLUParser.getData(result);
|
||||
temperature[i] = data.Temperature.toString();
|
||||
humidity[i] = data.Humidity.toString();
|
||||
sendToZoblak();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//BLE.Scanner.Subscribe(handleScanResult);
|
||||
BLE.Scanner.Start({ duration_ms: SCAN_DURATION, active: false }, handleScanResult);
|
||||
Reference in New Issue
Block a user