Gibt es eine Möglichkeit, mit einem Skript aus dem Shelly Blu Motion die Beleuchtungsstärke als Webhook im homee nutzbar zu machen? Und die Temperatur aus einem Shell Blu H&T Temperatursensor in homee zu übernehmen?
Kurz : Ja
Lang: die Suche ergibt folgendes
Um deinen Anforderungen gerecht zu werden müsstest du sehr viele HG schreiben.
Ansonsten musst du mit nem Pi arbeiten und alles über vhih als Device abbilden.
Dabei könnte ich dir auch unter die Arme greifen.
Leider besitze ich keinen Pi und möchte mir auch keinen zulegen. Schade, nachdem meine Shelly Door/Windows sehr gut funktionieren, hatte ich gehofft, dass es für weitere Shelly-Blu-Geräte auch entsprechende vorgefertigte Skripte gibt.
Gibt es Programmierer, die man, mit entsprechender Vergütung, beauftragen könnte @Poi?
Das Problem ist das du über das Script keine Variablen wie Lux oder Temperatur an den homee übergeben kannst.
Edit:
Was mir noch in den Sinn gekommen ist wäre ein esp32 der als Gateway Blu zu vhih fungieren kann.
Das würde ich mir mal anschauen und Feedback geben.
Dadurch das sowohl der Ble san auf dem esp läuft als auch vhih sehe ich da kein Problem drin.
Ich glaube die Anforderung hieß „kein extra Gerät“. Ein eps32 ist natürlich viel günstiger als ein PI, aber am Geld scheint es ja nicht zu scheitern, wenn @mak ein Skript in Auftrag geben will.
an sowas hatte ich auch schon gedacht.
Da es ja das esp vhih Projekt von @danil gibt.
Das zusammen mit nem Webserver ähnlich deinem Hue Cube
Edit: hab auch schon ein Script gefunden wo 15 min auf die BLU Gerät gehorcht wird um einfacher an die MAC Adressen der Geräte zu kommen.
Edit2:
hätte schon ne .txt mit den Attributen der Shelly
zu möglichen NodeProfilen und CAAttributen.
Dann würdest du dir zumindest diese Recherche sparen.
Die Profile und Attribute liegen bei mir auf dem Rechner
Ohne extra Gerät läuft es aktuell nicht.
Ansonsten sind die virtuellen Device ja in homee die man nutzen kann. Aber die Attribute lassen sich nicht über MQTT oder http api setzen sondern nur über einen websocket.
Um an den Access Token von homee zu kommen darf es verschiedener Bibliotheken die so nicht auf dem Shelly laufen bzw. Verfügbar sind.
Hi @mak,
ich besitze keine homee mehr. Ich bin kpl. auf Home Assistant gewechselt.
Ich kann dir aber ans Herz legen dich mal mit dem Shelly BLU Gateway auseinanderzusetzen! Ich war kurz davor das zu testen. Denn das Gateway wird über WLan eingebunden und sucht sich dann alle Shelly BLU Geräte zusammen. Diese kann man dann ansprechen.
Leider bin ich nicht mehr in der Lage das zu prüfen. Evtl. sind der Eine oder Andere schon dabei und haben Erfahrung damit.
Würde mich hier aber auch interessieren…
Das Shelly Blu Gateway habe ich im Einsatz, dein Script mit den Door/Windows-Sensoren läuft darauf sehr gut.
Nur fehlen jetzt für andere Shelly-BLU-Geräte solche Skripte, An denen wäre ich interessiert gewesen, z.B. für den BLU-HT (ein kleines, wasserdichtes Thermometer) und BLU-Motion (für das Auslesen der Beleuchtungsstärke) und dem Shelly Display. Alles in Verbindung mit homee. Was aber wohl nicht möglich ist, siehe Aussagen von Micha.
Wenn du die Möglichkeit in Betracht ziehst einen esp zu betreiben dann könnte ich dir den Code dafür schreiben.
Das mit dem esp wird wohl nichts werden.
Trotzdem habe ich nochmal eine Frage zum Script von @Poi, ich habe jetzt mehrere D/W-Sensor mit dem Script am Laufen und bin sehr zufrieden. Ich würde gerne mit dem Script noch die Temperatur vom Shelly Blu H&T auslesen und an ein virtuelles Gerät in homee senden. Die Auswertung könnte ich mit mehreren Homeegrammen hinbekommen.
Aber dazu sind bestimmt die Datentypen „True“ und „False“ die Falschen? Könnte man da für die Temperatur andere Felder verwenden?
Ja das kann man machen, wenn dir schwellwerte reichen.
Du kannst natürlich auch jedes einzelne grad als Auslöser nehmen wenn du nur eine gewisse Spanne hast, oder man schreibt das Script so das es individuell ein Event für den Webhook ableitet.
Nach dem Motto event=temp_${value}
Da musst du nur im homee den event entsprechend deklarieren.
Super, mir würde ein Schwellwert (für Fußbodenheizung) genügen.
wenn du mir dafür die Script-Zeile erstellen würdest, wäre mir geholfen.
Danke für deine Mühe.
Leider kann ich mangels H&T die Werte nicht auslesen und müsste das auf blauen Dunst machen.
Ich schau mir das gerne mal anhand eines blu motion Sensors an.
// ******************* START CHANGE HERE *******************
let CONFIG = {
debug: true,
active: false,
homeeip: 'homeeIP',
webhookkey: 'PersönlicherWebhookKeyaushomee', //nur der reine Key aus der URL ab "webhooks_key=" bis"&event=Status"
device: {
window:[
{
macAddresse : '00:00:00:00:00:00', // MAC Addresse des BLU Fenstersensor
value_0_WebHookName: '0000', // Event in homee für geschlossen
value_1_WebHookName: '1111'}, // Event in homee für geöffnet
{
macAddresse : '00:00:00:00:00:00', // Zweiter Sensor und mehr, wie der erste Sensor einfach in das Array einfügen
value_0_WebHookName: '0000', // Event keine Bewegung
value_1_WebHookName: '1111'}], // Event Bewegeung ->ENDE für device window!!
motion:[
{
macAddresse : '00:00:00:00:00:00', // MAC Addresse BLU Motionsensor
value_0_WebHookName: '0000', // Event keine Bewegung
value_1_WebHookName: '1111'}, // Event Bewegeung
{
macAddresse : '00:00:00:00:00:00', // Zweiter Sensor und mehr, wie der erste Sensor einfach in das Array einfügen
value_0_WebHookName: '0000', // Event keine Bewegung
value_1_WebHookName: '1111'}], // Event Bewegeung ->ENDE für device motion!!
temperature:[
{
macAddresse : '00:00:00:00:00:00', // MAC Addresse BLU Motionsensor
WebHookName: '0000'}, // Event Name Temperatur wird automatisch gesetzt
{
macAddresse : '00:00:00:00:00:00', // Zweiter Sensor und mehr, wie der erste Sensor einfach in das Array einfügen
WebHookName: '0000'}] // Event Name Temperatur wird automatisch gesetzt
},
allowedMacAddresses:[],
motionHandler: function ( eventData) {
CONFIG.device.motion.forEach(function(element){
if (element.macAddresse.toLowerCase() === eventData.address.toLowerCase()){
if (eventData.motion === 1 ){
webhookHandler(element.value_1_WebHookName)}
else if (eventData.motion === 0 ){
webhookHandler(element.value_0_WebHookName)}
else{}
}
else{}
})
},
windowHandler: function (eventData) {
CONFIG.device.window.forEach(function(element) {
if (element.macAddresse.toLowerCase() === eventData.address.toLowerCase()){
if (eventData.window === 1 ){webhookHandler(
element.value_1_WebHookName)}
else if (eventData.window === 0 ){
webhookHandler(element.value_0_WebHookName)}
else{}
}
else{}
})
},
// Handler Temperature
temperatureHandler: function (temperature, eventData) {
CONFIG.device.temperature.forEach(function(element) {
if (element.macAddresse.toLowerCase() === eventData.address.toLowerCase()){
webhookHandler(eventData.WebhookName + temperature)
}
else{}
})
},
// Handler Helligkeit
illuminanceHandler: function (illuminance, eventData) {
let topic = eventData.address + "/illuminance";
console.log(illuminance);
},
// Handler Status Update
onStatusUpdate: function (eventData) {}
};
// ******************* Webhook homee Function *******************
function webhookHandler(a){
console.log(a),
Shelly.call(
"HTTP.GET",
{url: 'http://'+CONFIG.homeeip+':7681/api/v2/webhook_trigger?webhooks_key='+CONFIG.webhookkey+'&event='+a},
function(result, error_code, error_message) {
print(result.body)
});
};
// ******************* STOP CHANGE HERE *******************
let ALLTERCO_MFD_ID_STR = "0ba9";
let BTHOME_SVC_ID_STR = "fcd2";
let uint8 = 0;
let int8 = 1;
let uint16 = 2;
let int16 = 3;
let uint24 = 4;
let int24 = 5;
//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);
}
// The BTH object defines the structure of the BTHome data
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 };
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;
},
// Unpacks the service data buffer from a Shelly BLU device
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;
},
};
function onReceivedPacket (data) {
if(CONFIG._processedMacAddresses !== null) {
if(CONFIG._processedMacAddresses.indexOf(data.address) < 0) {
//logger(["Received event from", data.address, "outside of the allowed addresses"], "Info");
//return;
}
}
if (
typeof CONFIG.motionHandler === "function" &&
typeof data.motion !== "undefined"
) {
CONFIG.motionHandler( data);
logger("Motion handler called", "Info");
}
if (
typeof CONFIG.windowHandler === "function" &&
typeof data.window !== "undefined"
) {
CONFIG.windowHandler(data);
logger("window handler called", "Info");
}
if (
typeof CONFIG.illuminanceHandler === "function" &&
typeof data.illuminance !== "undefined"
) {
CONFIG.illuminanceHandler(data.illuminance, data);
logger("Illuminance handler called", "Info");
}
if (
typeof CONFIG.temperatureHandler === "function" &&
typeof data.temperature !== "undefined"
) {
CONFIG.temperatureHandler(data.temperature, data);
logger("Temperature handler called", "Info");
}
if (typeof CONFIG.onStatusUpdate === "function") {
CONFIG.onStatusUpdate(data);
logger("New status update", "Info");
}
}
//saving the id of the last packet, this is used to filter the duplicated packets
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"
) {
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(unpackedData);
onReceivedPacket(unpackedData);
}
// 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");
}
}
if (
typeof CONFIG.allowedMacAddresses !== "undefined"
) {
if(CONFIG.allowedMacAddresses !== null) {
// Process configured mac addresses all to lower case and remove duplicates.
CONFIG._processedMacAddresses =
CONFIG
.allowedMacAddresses
.map(function (mac) { return mac.toLowerCase(); })
.filter(function (value, index, array) { return array.indexOf(value) === index; })
}
else {
CONFIG._processedMacAddresses = null;
}
}
//subscribe a callback to BLE scanner
BLE.Scanner.Subscribe(BLEScanCallback);
}
init();
@mak
Nimm mal bitte dieses Script und ergänze den Bereich für Temperature mit der Mac des BLU sensors und den ersten Teile deines Webhook Events
Beispiel in homee Event = temp10
Beispiel im Shelly WebhookName ‚temp‘
Die Zahl wird vom Script durch den Temperaturwert gesetzt.
Der Shelly sendet immer einen webhook mit den Temperaturen und sollte in homee dann das passende Event vorhanden sein wird dein HG gestartet.
Alles ungetestet da kein Temperaturwertgeber bei mir im Haus ist.
Viel erfolg
Jetzt hast du nur noch das Problem das du beim virtuellen Temperatur Sensor den Wert nicht über ein HG ändern kannst.
Hierfür könntest du dann nur wieder etwas tricksen. HG anlegen mit dem Auslöser Webhook und dann ein virtuelles Device mit Dimmer als Aktion auswählen.
Danach musst du mein Tool homee-tool.de öffnen und dann im HG ein Device Wechsel vornehmen. Ich schau mir mal alles genau an und beschreibe dir das gerne nochmal genauer.
Vorgehen:
- Virtuelles Device mit Attribut Dimmer anlegen
- Virtuelles Device mit Attribut Temperatur anlegen
- HG mit Abspielbutton anlegen
- homee-tool.de öffnen und mit dem homee verbinden
- zusätzliche Daten anzeigen drücken
- rechts auf die Homeegramme klicken und das zuletzt angelegte suchen ( Name )
- hier die ID hinter dem Namen merken oder notieren
- rechts auf die Geräte klicken und das virtuelle Temperatur Device suchen und anklicken , hier die Node ID und die Attribut ID notieren
- danach links im Eingabefeld ( Nachricht an Websocket ) folgendes eigeben mit den entsprechenden ID POST:homeegrams/845/actions?node_id=3494&attribute_id=9165&value=10&command=1&delay=0&type=1
- die 845 wird in diesem Fall deine vorher notierte HG ID , die 3494 muss durch deine Node ID getauscht werden und die 9165 ist deine Attribut ID vom Virtuellen sensor
- dann auf Nachricht senden klicken und fertig
- im homee kannst du nun das HG duplizieren und bearbeiten mit deinen werten für Webhook Event und auch Zielwert des Sensors
Damit hast du nun die Möglichkeit den Wert über ein HG zu ändern.
Viel Spass