Hallo zusammen,
vielen Dank an alle Mitglieder hier im Forum, ich konnte bereits sehr strukturiert sehr viele Infos und auch andere scripte finden, was mir schon etwas weitergeholfen hat.
Ich bin gerade dabei unseren Kastenwagen (Clever Runner 636) mit einer kleinen Alarmanlage auszustatten.
Diese soll falls jemand bereits im Fahrzeug ist, eine Sirene anschalten und den vermeintlichen Dieb maximal stören. Bzw. auch für eine gewisse Aufmerksamkeit auf dem Parkplatz zu sorgen. Ich würde sie anschalten, wenn ich beim Einkaufen bin oder in der Nähe am Strand bin.
Meine Anforderungen:
Alarmanlage soll über BluButton "scharf" eingeschaltet und ausgeschaltet werden.
2 BluMotion die, die Sirene bei scharfer Alarmanlage aufheulen lassen. (Ein BluMotion für die Hecktüre, den anderen für Seitentür und Dinette)
Bei Bewegung soll die Sirene konstant aufheulen.
Bei Fehlalarm soll jedoch nur für kurze Zeit (3 Sekunden) die Sirene an sein.
Alles soll auch ohne Internet funktionieren.
Alles mit 12V betreiben.
Meine Hardware:
1 Shelly Plus 1 FW20240130-115220 1.2.0 beta1
2 BluButton mit FW 20240115-142202 v1.0.9
2 BluMotion mit FW 20240202-140530 (mittlerweile gibt's schon 20240207 v1.0.9 hotfix 1) (Blindtime auf 30s, beacon false, sensitivity 2, pulseCount 1,)
1 Sirene 6 Töne von Aliexpress "15 Watt" angeschlossen am Shelly Plus 1
So weit funktioniert das Grundkonzept, jedoch bin ich noch nicht zufrieden.
Mein Problem:
Da bei "konstanter" Bewegung nichts vom BluMotion geschickt wird, ist die Sirene jetzt immer nur 3 Sekunden an.
Solange die Bewegung erkannt wird, wird keine weitere Nachricht geschickt.
Wenn ich auf "Motion on" und "Motion Off" triggere, würde beim Fehlalarm die Sirene 30 Sekunden an sein.
Hat jemand eine Idee wie ich bei scharfer Alarmanlage,die Sirene öfter bzw. konstant anbekommen?
Blindtime runtersetzten (auf 2 Sekunden) geht wohl nicht beim BluMotion?
BeaconMode geht nur auf minimal 30 Sekunden.
Ein höherer Stromverbrauch wäre nicht sonderlich tragisch, das die Alarmanlage nur einige Stunden pro Tag im Urlaub laufen würde.
Eventuell kann man die BluMotion per script per Timer alle 2 Sekunden abfragen, sobald eine erste Bewegung erkannt wurde?
Mein Script habe ich primär von hier kopiert:
Shelly BLU Motion - Bluetooth Bewegungsmelder
welches wohl zu 90% vom github kopiert ist.
Grüße und Danke im Voraus!
Tobias
// v0.1
// https://haus-automatisierung.com/hardware/shelly/2023/09/02/shelly-blu-motion.html
/******************* START CHANGE HERE *******************/
let CONFIG = {
// Specify the destination event where the decoded BLE data will be emitted. It allows for easy identification by other applications/scripts
eventName: "shelly-bluMotion",
// When set to true, debug messages will be logged to the console
debug: true,
// When set to true and the script ownes the scanner, the scan will be active.
// Active scan means the scanner will ping back the Bluetooth device to receive all its data, but it will drain the battery faster
active: false,
//merker
AlarmAnlageAN: false,
// The mac address of Shelly BLU Motion and Buttons
macMotion1: "b0:c7:de:60:11:22", //11:22 Datenschutz
macMotion2: "b0:c7:de:c5:11:22",
macButton1: "f4:b3:b1:82:11:22",
macButton2: "e8:e0:7e:bd:11:22",
onMotionChange: function(motion)
{
//Shelly.call("Switch.set", { "id": 0, "on": motion }); //DauerSirene
if(CONFIG.AlarmAnlageAN){
if(motion === true)
{
Shelly.call("Switch.set", {"id": 0, "on": true, "toggle_after": 3}); // 3000ms an
}
}
console.log("Motion seen:", motion);
},
//onSinglePush
onSinglePush: function(pushes)
{
//CONFIG.AlarmAnlageAN = ! CONFIG.AlarmAnlageAN; //toggeln
console.log("Pushes amount: ", pushes);
if(pushes === 1) // 1x push = AUS
{
CONFIG.AlarmAnlageAN = false;
Shelly.call("Switch.set", {"id": 0, "on": false}); // AUS
}
else if(pushes === 2) // 2x push = AN
{
CONFIG.AlarmAnlageAN = true;
Shelly.call("Switch.set", {"id": 0, "on": true, "toggle_after": 0.01}); // 10ms an
}
else if(pushes === 254) // PanicMode
{
CONFIG.AlarmAnlageAN = false;
Shelly.call("Switch.set", {"id": 0, "on": true}); // DAUER AN PanicMode
}
else if(pushes === 4) // Aus
{
CONFIG.AlarmAnlageAN = false;
Shelly.call("Switch.set", {"id": 0, "on": false}); // button losgelassen
}
},
};
/******************* STOP CHANGE HERE *******************/
/******************* STOP CHANGE HERE *******************/
let BTHOME_SVC_ID_STR = "fcd2";
let uint8 = 0;
let int8 = 1;
let uint16 = 2;
let int16 = 3;
let uint24 = 4;
let int24 = 5;
let BTH = {};
BTH[0x00] = { n: "pid", t: uint8 };
BTH[0x01] = { n: "battery", t: uint8, u: "%" };
BTH[0x02] = { n: "temperature", t: int16, f: 0.01, u: "tC" };
BTH[0x03] = { n: "humidity", t: uint16, f: 0.01, u: "%" };
BTH[0x05] = { n: "illuminance", t: uint24, f: 0.01 };
BTH[0x21] = { n: "motion", t: uint8 };
BTH[0x2d] = { n: "window", t: uint8 };
BTH[0x3a] = { n: "button", t: uint8 };
BTH[0x3f] = { n: "rotation", t: int16, f: 0.1 };
// Logs the provided message with an optional prefix to the console.
function logger(message, prefix) {
// exit if the debug isn't enabled
if (!CONFIG.debug) {
return;
}
let finalText = "";
// if the message is list loop over it
if (Array.isArray(message)) {
for (let i = 0; i < message.length; i++) {
finalText = finalText + " " + JSON.stringify(message[i]);
}
} else {
finalText = JSON.stringify(message);
}
// the prefix must be string
if (typeof prefix !== "string") {
prefix = "";
} else {
prefix = prefix + ":";
}
// log the result
console.log(prefix, finalText);
}
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;
}
// functions for decoding and unpacking the service data from Shelly BLU devices
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") {
logger("unknown type", "BTH");
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 lastPacketId = 0x100;
// Callback for the BLE scanner object
function bleScanCallback(event, result) {
//exit if not a result of a scan
if (event !== BLE.Scanner.SCAN_RESULT) {
return;
}
//exit if service_data member is missing
if (
typeof result.service_data === "undefined" ||
typeof result.service_data[BTHOME_SVC_ID_STR] === "undefined"
) {
//logger("Missing service_data member", "Error");
//print(result);
return;
}
let unpackedData = BTHomeDecoder.unpack(
result.service_data[BTHOME_SVC_ID_STR]
);
//exit if unpacked data is null or the device is encrypted
if (
unpackedData === null ||
typeof unpackedData === "undefined" ||
unpackedData["encryption"]
) {
logger("Encrypted devices are not supported", "Error");
return;
}
// exit if the event is duplicated
if (lastPacketId === unpackedData.pid) {
return;
}
lastPacketId = unpackedData.pid;
unpackedData.rssi = result.rssi;
unpackedData.address = result.addr;
console.log("Received " + JSON.stringify(unpackedData));
if ((unpackedData.address === CONFIG.macMotion1 ||
unpackedData.address === CONFIG.macMotion2)
&& typeof unpackedData.motion !== "undefined")
{
CONFIG.onMotionChange(unpackedData.motion === 1);
}
if ((unpackedData.address === CONFIG.macButton1 ||
unpackedData.address === CONFIG.macButton2)
&& typeof unpackedData.button !== "undefined")
{
print(unpackedData);
CONFIG.onSinglePush(unpackedData.button);
}
}
// Initializes the script and performs the necessary checks and configurations
function init() {
// exit if can't find the config
if (typeof CONFIG === "undefined") {
console.log("Error: Undefined config");
return;
}
// get the config of ble component
let bleConfig = Shelly.getComponentConfig("ble");
// exit if the BLE isn't enabled
if (!bleConfig.enable) {
console.log("Error: The Bluetooth is not enabled, please enable it from settings");
return;
}
// check if the scanner is already running
if (BLE.Scanner.isRunning()) {
console.log("Info: The BLE gateway is running, the BLE scan configuration is managed by the device");
} else {
// start the scanner
let bleScanner = BLE.Scanner.Start({
duration_ms: BLE.Scanner.INFINITE_SCAN,
active: CONFIG.active
});
if (!bleScanner) {
console.log("Error: Can not start new scanner");
}
}
//subscribe a callback to BLE scanner
BLE.Scanner.Subscribe(bleScanCallback);
}
init();
Alles anzeigen