wie es im Foto den Anschein hat, sind 2 Niederspannungstaster der original-Steuerung durch Shelly zu ersetzen
(oder mit parallelen Shelly zur Steuerung zu nutzen),
dann brauchst du auch 2x Shelly 1 Gen 3 oder Gen4 .
Je Taster einen.
Beiträge von bp4willi
-
-
PS. Da sich Home und Remote Shelly , wenn sie zeitgleich senden ins Gehege kommen, haben wir in die Sendefunktion für Wiederholungen des Paket sendens, eine Zeitvariabilität eingebaut, dass die Wiederholungen zufällig im Range von 10 bis 20 Sekunden passieren, damit die Gegenstelle auch Zeit hat durchzukommen und ihr Sendepaket abzusetzen. Die Anzahl der Wiederholungen ("MAX_RETRIES") hatten wir in unserem Beipiel auf der Remote Seite auf 100 und auf der Home Seite auf 8 gesetzt. Bei einer stabilen Funkverbindung reichen vieleicht auch 4.
Aufgrund der vermuteten Begrenztheit der Shelly Kapazität, haben wir die Anzahl der parallel zum Versand anstehenden Texte/Befehle auf maximal 4 begrenzt ("MAX_CONCURRENT_CALLS = 4").
Sonst kommen sich die Sende-Wiederholungen und die Acknowledgements der Gegenseite ggf. zu sehr ins Gehege und blockieren sich dann gegenseitig. wir hatten festgestellt, dass ein Paket senden etwa 2-3 sekunden braucht. -
Hier die von uns verwendeten LoRa Skripte auf der Home und Remote Seite.
Beide Seiten sind sowohl Sender, wie auch Empfänger.Auf beiden Seiten werden im Shelly virtuelle Komponenten genutzt, als Mittler zwischen der LoRa-Funk-Welt und den Shelly Aktionen auf die physikalischen Shelly-Funktionen im Heimnetz.
Das versprach Flexibilität in der Anwendung, weil über LoRa beliebige Texte transportiert werden, die dann je nach definiertem Text, für jede Menge variabler Funktionen als Trigger dienen können, -- über ein einzelnes Text Ein- oder Ausgabefeld.
Es werden einfach die Texte in den Aktionen definiert, die gesendet werden, - oder die als Trigger für eine Aktion fungieren.
Im Beispiel geht es um die Fernalarmierung einer Statusänderung am Remote Shelly.
Durch den Home Shelly kann dann wiederum eine Aktion am Remote Shelly getriggert werden.Home Shelly:
virtual Components:
button:200 , button:201 -- zur Steuerung einer Remote Komponente;
text:200 -- zur Darstellung empfangener (remote Shelly) Textnachricht auf dem Home Shelly
(z.B. Eingangs-Status remote Shelly)
number:200 , number:201 -- zur Darstellung des Packet transmission failCode: comms-LoRa-Home.js
Alles anzeigen// #### comms-LoRa-Home.js #### // #### Shelly local input #### let btnOff = Virtual.getHandle("button:200"); btnOff.on("single_push", function(ev) { console.log("Button OFF"); sendPacket(PACKET_TYPE_COMMAND, "turn_alarm_off"); }); let btnOn = Virtual.getHandle("button:201"); btnOn.on("single_push", function(ev) { console.log("Button ON"); sendPacket(PACKET_TYPE_COMMAND, "turn_alarm_on"); }); // #### Shelly local output #### function onReceiveStatus(statusText) { let alarm = Virtual.getHandle("text:200"); alarm.setValue(statusText); } function onReceiveCommand(commandText) { /* no-op */ } // #### display count of unconfirmed transmissions #### function onUpdatePaketsWaiting(count) { let number = Virtual.getHandle("number:200"); number.setValue(count); } function onUpdatePacketsLost(count) { let number = Virtual.getHandle("number:201"); number.setValue(count); } // #### Start of common script #### const MAX_RETRIES = 8; const MIN_RETRY_INTERVAL = 10000; const MAX_RETRY_INTERVAL = 20000; const MAX_CONCURRENT_CALLS = 4; // #### encryption - decryption functions #### const KEY_RAW = "<put your encryption key here>"; function keyFromHex(hex) { const buffer = new ArrayBuffer(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { buffer[i / 2] = parseInt(hex.substr(i, 2), 16); } return buffer; } const KEY = keyFromHex(KEY_RAW); const AES_MODE = "ECB"; function encrypt(plaintext, key) { //console.log("Encrypting: ", plaintext); function stringToBlockBuffer(string, blocksize) { let size = string.length; const lastBlock = string.length % blocksize; if (lastBlock > 0) { size += blocksize - lastBlock; } const buffer = new ArrayBuffer(size); let i = 0; for (; i < string.length; i++) { buffer[i] = string.charCodeAt(i); } for (; i < size; i++) { buffer[i] = 0; } return buffer; } return AES.encrypt(stringToBlockBuffer(plaintext, 16), key, { mode: AES_MODE }); } function decrypt(cyphertext, key) { function bufferToString(buffer) { let string = ''; for (let i = 0; i < buffer.length; i++) { const code = buffer[i]; if (code == 0) continue; string += String.fromCharCode(buffer[i]); } return string; } const buffer = AES.decrypt(cyphertext, key, { mode: 'ECB' }); if (!buffer || buffer.byteLength === 0) { console.log('Could not decrypt message'); return; } return bufferToString(buffer); } function numberToHex(n, size) { let string = n.toString(16); while (string.length < size) { string = '0' + string; } return string.slice(-size); } function checksum(text, size) { let checksum = 0; for (let i = 0; i < text.length; i++) { checksum ^= text.charCodeAt(i); } return numberToHex(checksum , size); } // #### packet tracking functions #### const CHECKSUM_SIZE = 4; const PACKET_TYPE_SIZE = 1; const PACKET_ID_SIZE = 2; const PACKET_TYPE_STATUS = "S"; const PACKET_TYPE_COMMAND = "C"; const PACKET_TYPE_ACK = "A"; var checkAcknowledgementsTimer = undefined; function generatePacket(type, id, text) { let packet = type + id + text; packet = checksum(packet, CHECKSUM_SIZE) + packet; return packet; } let nextPacketId = 0; var receivedAcknowledgments = [ ]; var awaitsAcknowledgment = { }; function sendPacket(type, text) { const id = numberToHex(nextPacketId++, PACKET_ID_SIZE); const packet = generatePacket(type, id, text); awaitsAcknowledgment[id] = { "packet": packet, "retries": 0, }; loraSend(packet); updatePacketsWaiting(); setCheckAcknowledgementsTimer(); } function sendAcknowledgment(id) { const packet = generatePacket(PACKET_TYPE_ACK, id, ''); loraSend(packet); } function receivePacket(packet) { if (packet.length < CHECKSUM_SIZE + PACKET_TYPE_SIZE + PACKET_ID_SIZE) { console.log("Error: Packet too short"); return; } const actualChecksum = packet.slice(0, CHECKSUM_SIZE); const afterChecksum = packet.slice(CHECKSUM_SIZE); const expectedChecksum = checksum(afterChecksum, CHECKSUM_SIZE); if (actualChecksum !== expectedChecksum) { console.log("Error: Checksum mismatch"); return; } const packetType = afterChecksum.slice(0, PACKET_TYPE_SIZE); const packetId = afterChecksum.slice(PACKET_TYPE_SIZE, PACKET_TYPE_SIZE + PACKET_ID_SIZE); const text = afterChecksum.slice(PACKET_TYPE_SIZE + PACKET_ID_SIZE); console.log("Received {type:"+packetType+",id:"+packetId+",text:'"+text+"'}"); switch (packetType) { case PACKET_TYPE_STATUS: onReceiveStatus(text); break; case PACKET_TYPE_COMMAND: onReceiveCommand(text); break; case PACKET_TYPE_ACK: console.log("Received acknowledgment for packet " + packetId); receivedAcknowledgments.push(packetId); delete awaitsAcknowledgment[packetId]; updatePacketsWaiting(); setCheckAcknowledgementsTimer(); return; default: console.log("Error: Unknown packet type"); return } sendAcknowledgment(packetId); } // #### LoRa send- receive functions #### var concurrentCalls = 0; function loraSend(packet) { console.log("Sending: ", packet); const encoded = btoa(encrypt(packet, KEY)); if (concurrentCalls >= MAX_CONCURRENT_CALLS) { console.log("Error: Too many concurrent calls, skipping ..."); return; } concurrentCalls++; Shelly.call( 'Lora.SendBytes', { id: 100, data: encoded }, function (_, err_code, err_msg) { if (err_code !== 0) { console.log('Error:', err_code, err_msg); } concurrentCalls--; } ); } function loraReceive(data) { const packet = decrypt(atob(data), KEY); if (!packet) { return; } console.log("Received: ", packet); receivePacket(packet); } Shelly.addEventHandler(function (event) { if ( typeof event !== 'object' || event.name !== 'lora' || !event.info || !event.info.data ) { return; } loraReceive(event.info.data); }); var totalPacketsLost = 0; function updatePacketsWaiting() { onUpdatePaketsWaiting(Object.keys(awaitsAcknowledgment).length); } function updatePacketsLost() { updatePacketsWaiting(); onUpdatePacketsLost(totalPacketsLost); } function checkAcknowledgements() { for (const id of receivedAcknowledgments) { delete awaitsAcknowledgment[id]; } receivedAcknowledgments = []; const waiting = Object.keys(awaitsAcknowledgment); updatePacketsWaiting(); if (waiting.length === 0) { console.log("No packets waiting"); return; } for (const id of waiting) { const entry = awaitsAcknowledgment[id]; if (entry.retries >= MAX_RETRIES) { console.log("Error: Packet " + id + " not acknowledged after " + MAX_RETRIES + " retries"); delete awaitsAcknowledgment[id]; totalPacketsLost++; onUpdatePacketsLost(totalPacketsLost); continue; } console.log("Retrying packet " + id + ", retries left: " + (MAX_RETRIES - entry.retries)); entry.retries++; loraSend(entry.packet); anyRetry = true; } setCheckAcknowledgementsTimer(); } function setCheckAcknowledgementsTimer() { if (checkAcknowledgementsTimer) { return; } const interval = MIN_RETRY_INTERVAL + Math.random() * (MAX_RETRY_INTERVAL - MIN_RETRY_INTERVAL); console.log("Setting timer to check acknowledgments in " + interval + " ms"); checkAcknowledgementsTimer = Timer.set(interval, false, function() { checkAcknowledgementsTimer = undefined; checkAcknowledgements(); }); }Remote Shelly:
virtual Components:
text:200 , text:201 -- zur Darstellung von zu sendenden (remote Shelly) oder empfangenen (Home Shelly) Textnachricht ;
(z.B. senden des remote Shelly Eingangs-Status ; Empfang des Kommandos vom Home Shelly)
number:200 , number:201 -- zur Darstellung des Packet transmission failCode: comms-Lora-Remote.js
Alles anzeigen// #### comms-Lora-Remote.js #### // #### Shelly local input #### let alarm = Virtual.getHandle("text:200"); alarm.on("change", function(ev) { console.log("Alarm changed: ", ev.value); sendPacket(PACKET_TYPE_STATUS, ev.value); }); // #### Shelly local output #### function onReceiveStatus(statusText) { /* no-op */ } function onReceiveCommand(commandText) { let command = Virtual.getHandle("text:201"); command.setValue(commandText); } // #### display count of unconfirmed transmissions #### function onUpdatePaketsWaiting(count) { let number = Virtual.getHandle("number:200"); number.setValue(count); } function onUpdatePacketsLost(count) { let number = Virtual.getHandle("number:201"); number.setValue(count); } // #### Start of common script #### const MAX_RETRIES = 100; const MIN_RETRY_INTERVAL = 10000; const MAX_RETRY_INTERVAL = 20000; const MAX_CONCURRENT_CALLS = 4; // #### encryption - decryption functions #### const KEY_RAW = "<put your encryption key here>"; function keyFromHex(hex) { const buffer = new ArrayBuffer(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { buffer[i / 2] = parseInt(hex.substr(i, 2), 16); } return buffer; } const KEY = keyFromHex(KEY_RAW); const AES_MODE = "ECB"; function encrypt(plaintext, key) { //console.log("Encrypting: ", plaintext); function stringToBlockBuffer(string, blocksize) { let size = string.length; const lastBlock = string.length % blocksize; if (lastBlock > 0) { size += blocksize - lastBlock; } const buffer = new ArrayBuffer(size); let i = 0; for (; i < string.length; i++) { buffer[i] = string.charCodeAt(i); } for (; i < size; i++) { buffer[i] = 0; } return buffer; } return AES.encrypt(stringToBlockBuffer(plaintext, 16), key, { mode: AES_MODE }); } function decrypt(cyphertext, key) { function bufferToString(buffer) { let string = ''; for (let i = 0; i < buffer.length; i++) { const code = buffer[i]; if (code == 0) continue; string += String.fromCharCode(buffer[i]); } return string; } const buffer = AES.decrypt(cyphertext, key, { mode: 'ECB' }); if (!buffer || buffer.byteLength === 0) { console.log('Could not decrypt message'); return; } return bufferToString(buffer); } function numberToHex(n, size) { let string = n.toString(16); while (string.length < size) { string = '0' + string; } return string.slice(-size); } function checksum(text, size) { let checksum = 0; for (let i = 0; i < text.length; i++) { checksum ^= text.charCodeAt(i); } return numberToHex(checksum , size); } // #### packet tracking functions #### const CHECKSUM_SIZE = 4; const PACKET_TYPE_SIZE = 1; const PACKET_ID_SIZE = 2; const PACKET_TYPE_STATUS = "S"; const PACKET_TYPE_COMMAND = "C"; const PACKET_TYPE_ACK = "A"; var checkAcknowledgementsTimer = undefined; function generatePacket(type, id, text) { let packet = type + id + text; packet = checksum(packet, CHECKSUM_SIZE) + packet; return packet; } let nextPacketId = 0; var receivedAcknowledgments = [ ]; var awaitsAcknowledgment = { }; function sendPacket(type, text) { const id = numberToHex(nextPacketId++, PACKET_ID_SIZE); const packet = generatePacket(type, id, text); awaitsAcknowledgment[id] = { "packet": packet, "retries": 0, }; loraSend(packet); updatePacketsWaiting(); setCheckAcknowledgementsTimer(); } function sendAcknowledgment(id) { const packet = generatePacket(PACKET_TYPE_ACK, id, ''); loraSend(packet); } function receivePacket(packet) { if (packet.length < CHECKSUM_SIZE + PACKET_TYPE_SIZE + PACKET_ID_SIZE) { console.log("Error: Packet too short"); return; } const actualChecksum = packet.slice(0, CHECKSUM_SIZE); const afterChecksum = packet.slice(CHECKSUM_SIZE); const expectedChecksum = checksum(afterChecksum, CHECKSUM_SIZE); if (actualChecksum !== expectedChecksum) { console.log("Error: Checksum mismatch"); return; } const packetType = afterChecksum.slice(0, PACKET_TYPE_SIZE); const packetId = afterChecksum.slice(PACKET_TYPE_SIZE, PACKET_TYPE_SIZE + PACKET_ID_SIZE); const text = afterChecksum.slice(PACKET_TYPE_SIZE + PACKET_ID_SIZE); console.log("Received {type:"+packetType+",id:"+packetId+",text:'"+text+"'}"); switch (packetType) { case PACKET_TYPE_STATUS: onReceiveStatus(text); break; case PACKET_TYPE_COMMAND: onReceiveCommand(text); break; case PACKET_TYPE_ACK: console.log("Received acknowledgment for packet " + packetId); receivedAcknowledgments.push(packetId); delete awaitsAcknowledgment[packetId]; updatePacketsWaiting(); setCheckAcknowledgementsTimer(); return; default: console.log("Error: Unknown packet type"); return } sendAcknowledgment(packetId); } // #### LoRa send- receive functions #### var concurrentCalls = 0; function loraSend(packet) { console.log("Sending: ", packet); const encoded = btoa(encrypt(packet, KEY)); if (concurrentCalls >= MAX_CONCURRENT_CALLS) { console.log("Error: Too many concurrent calls, skipping ..."); return; } concurrentCalls++; Shelly.call( 'Lora.SendBytes', { id: 100, data: encoded }, function (_, err_code, err_msg) { if (err_code !== 0) { console.log('Error:', err_code, err_msg); } concurrentCalls--; } ); } function loraReceive(data) { const packet = decrypt(atob(data), KEY); if (!packet) { return; } console.log("Received: ", packet); receivePacket(packet); } Shelly.addEventHandler(function (event) { if ( typeof event !== 'object' || event.name !== 'lora' || !event.info || !event.info.data ) { return; } loraReceive(event.info.data); }); var totalPacketsLost = 0; function updatePacketsWaiting() { onUpdatePaketsWaiting(Object.keys(awaitsAcknowledgment).length); } function updatePacketsLost() { updatePacketsWaiting(); onUpdatePacketsLost(totalPacketsLost); } function checkAcknowledgements() { for (const id of receivedAcknowledgments) { delete awaitsAcknowledgment[id]; } receivedAcknowledgments = []; const waiting = Object.keys(awaitsAcknowledgment); updatePacketsWaiting(); if (waiting.length === 0) { console.log("No packets waiting"); return; } for (const id of waiting) { const entry = awaitsAcknowledgment[id]; if (entry.retries >= MAX_RETRIES) { console.log("Error: Packet " + id + " not acknowledged after " + MAX_RETRIES + " retries"); delete awaitsAcknowledgment[id]; totalPacketsLost++; onUpdatePacketsLost(totalPacketsLost); continue; } console.log("Retrying packet " + id + ", retries left: " + (MAX_RETRIES - entry.retries)); entry.retries++; loraSend(entry.packet); anyRetry = true; } setCheckAcknowledgementsTimer(); } function setCheckAcknowledgementsTimer() { if (checkAcknowledgementsTimer) { return; } const interval = MIN_RETRY_INTERVAL + Math.random() * (MAX_RETRY_INTERVAL - MIN_RETRY_INTERVAL); console.log("Setting timer to check acknowledgments in " + interval + " ms"); checkAcknowledgementsTimer = Timer.set(interval, false, function() { checkAcknowledgementsTimer = undefined; checkAcknowledgements(); }); }Für die Encryption muss bitte jeder seinen eigenen persönlichen encryption key definieren (lange Zeichen+Ziffernfolge), und an der Skriptstelle KEY_RAW zwischen den Gänsefüßchen einfügen.
Wir hoffen, dass dies hilfreich ist für neue LoRa Projekte.
Mit Reichweiten-Test bin ich noch nicht weitergekommen.
Die bisherigen Ergebnisse waren ernüchternd, und eher im Range von 500m (und nicht 5km). -
tvbshelly da die skripte nicht mein geistiges Eigentum sind, muss ich das erst klären. Melde mich.
-
Habe dieses WE die LoRa module mit zwei Shelly1 Gen3 getestet. Mein Informatik talentierter Sohn hat mit den Skripten geholfen.
Basierend auf den Beispiel-Skripten zum encrypted send und Receiver, haben wir erst eine Methode über virtuelle Komponenten als Mittler entwickelt.
Da LoRa ja Text überträgt, haben den Shellys virtuelle Textfelder hinzugefügt. Über Texte die man dort über Kommandos in Aktionen, Szenen oder rpc calls einträgt, kann die LoRa Übertragung getriggert werden. Und die Texte können als Kommandos auf der Empfangsseite genutzt werden.
Damit haben wir dann die Reichweite getestet. Weiter als 500m sind wir noch nicht gekommen. Standen aber Gebäude und natürlich die Fensterscheibe dazwischen.
Außerdem war dann der Signalempfang, und entsrechende Schaltvorgänge nicht zuverlässig.
Da von Hause aus kein automatischer Rückkanal mit Acknowledge vorgesehen ist,
hat mein Sohn encrypted send und receive in einem Skript kombiniert und mit einem Paket Tracking und einer automatischen Sendewiederholung programmiert. Das ganze wird über counter als virtuelle Komponenten dokumentiert. Paket acknowledgement pending, und paket acknowledge failed, nachdem die einstellbare Zahl an re-tries nicht erfolgreich zu einem Acknowledge des Empfängers führte.
Damit will ich demnächst neue mobile Reichweiten Tests ausführen.
-
Pro 3EM im Hausanschlusskasten. Der misst, ob du Solarstrom über hast, und kann dann andere Shellys ansteuern.
-
tvbshelly hätte dann nicht für den 1Mini Gen4 in der Bedienungsanleitung der Hinweis auf SELV/PELV auch drin sein müssen, so wie in der Anleitung zum 1Mini Gen3 ??
-
funkenwerner die Antwort hat keinen hinreichenden Bezug zu meiner Frage. Es geht um 1Mini Gen4
-
Hi,
In der Anleitung vom 1 Mini Gen3 stand noch der Hinweis, dass keine SELV/PELV Kleinspannungskomponenten an die Lastanschlüsse angeschl ssen werden dürfen.
In der Anleitung zum 1 Mini Gen4 fehlt dieser Hinweis.
Heißt das, dass der Mini Gen4 so konstruktiv optimiert wurde, dass die nötigen Abstände der Leiterbahnen im Gerät eingehalten werden, und SELV/PELV Geräte sicher damit betrieben werden können ??
-
Ok, da liegt ein Missverständnis vor.
Zuerst war die Spannungsversorgung des Mini1 an den Ausgang des Mini1PM angeschlossen. Hat sich nicht bewährt, da der Mini1PM zu häufig geschaltet hat (weil in Aktionen keine Zeitsperre haben) und der nachrangige Mini1 deshalb in den Anlernmodus ging.
Danach hatte ich den Mini1 direkt an der Phase für die Stromversorgung, und der Ausgang des Mini1PM hat den SW Eingang des Mini1 angesteuert. (Detached mode) Gleichzeitig war der Ausgang des Mini1PM parallel über den NTC mit dem Ladegerät verbunden. Das hat sich auch nicht bewährt, weil anscheinend Spannung der Eingangsstufe des Ladegerätes auf den SW Eingang des Mini1 rückgewirkt hat. Der Mini1 Eingang blieb "grün" und das Relais eingeschaltet.
Deshalb in letzter Konsequenz die physikalische Kopplung der Mini1PM und Mini1 gekappt, und die Ansteuerung des Mini1 durch den Mini1PM nur durch eine Aktion realisiert. Das funktioniert bisher verlässlich.
Ich hoffe das klärt es hinreichend.
-
An dem Mini1 gibt es dank NTC keinen hohen Einschaltstrom und wenn nur der Kontakt geklebt hätte wäre der Shelly nicht als aktiviert/"on" in der App angezeigt worden.
Spannung am SW Eingang des Mini1 hab ich zu dem Zeitpunkt nicht gemessen.
Ohne angeschlossenes Ladegerät haben beide Shelly Mini ordnungsgemäß geschaltet.
-
Hinter den Shelly mini 1PM Gen3, der eigentlich das Ladegerät einschaltet, habe ich an den Lastausgang
einen Shelly mini 1 Gen3 angeschlossen, den ich so konfiguriert habe, dass er automatisch nach 1sec einschaltet, sobald er mit Strom versorgt wird (vom 1PM). Der Shelly mini 1 braucht also nur Strom (Verlustleistung 0,6W), wenn der Shelly mini 1PM eingeschaltet ist.Das hat sich leider nicht bewährt. In Konstellation mit Aktionen können die Shelly ja unverzögert hin und her schalten, je nach erfüllter Bedingung.
Der Mini 1PM hat heute wohl den Mini 1 mehr als 4x in einer Minute mit Strom versorgt und wieder ausgeschaltet. Das hat dazu geführt, dass der Mini1 wieder in den Anlernmodus gegangen ist (rote LED blinkt) und gar nichts mehr geschaltet hat.
Mal wieder eine neue Shelly (un)Funktion gelernt, die nicht im Handbuch/Beipackzettel steht.
(Doof. Es gibt doch den Resettaster)
Habe jetzt umverkabelt. Sowohl Mini1PM und nachgeschalteter Mini1 sind jetzt permanent am Strom.
Verzögerte Aktivierung und sofortige Deaktivierung des Mini1 durch den Mini1PM über Aktionen. Nicht über die Steuerleitung des Mini1.
Denn die Eingangskondensatoren des nachgeschalteten Ladegerätes haben über den durchgeschalteten Mini1 Relaiskontakt auch den SW Eingang des Mini1 auf "on" gehalten. Der schaltete gar nicht mehr ab. Auch als detached Eingang nicht.
Bei den Shellys muss man schon ziemlich um die Ecke denken, um das Geraffel ans laufen zu bringen.
-
crazyman69 ja , leider geht das nur mit Szenen via Cloud, also mit Internetverbindung (und funktionierendem Server in Bulgarien).
Mit lokalen Aktionen geht das nicht. Da können die Shellys wild hin und her schalten, da sie sich direkt über http Befehle ansprechen. Und im http Befehlssortiment ist keine Funktion implementiert, die für eine definierte Zeit nachfolgende Befehle ignorieren würde.
Das wäre echt hilfreich für viele Anwendungen und zu schön um wahr zu sein.
-
Der Inhalt kann nicht angezeigt werden, da Sie keine Berechtigung haben, diesen Inhalt zu sehen. -
Kann man ja ein externes 3v Netzteil dranbasteln
-
Der Button in der App steuert direkt das Relais an und nicht irgendwelche Szenen oder Aktionen.
Wenn du mit einem Button in der App irgendwas komplexes ansteuern willst musst du dir am Shelly plus 1 eine virtuelle Gruppe mit einen virtuellen Taster oder Schalter anlegen. Den virtuellen Taster/Schalter kannst dir dann als Button in der App ablegen und mit deiner Aktion oder Skript verknüpfen (afaik)
-
Meiner unqualifizierten Ansicht nach, bezieht sich SELV auf Schutzkleinspannung wo der Nutzer ggf Berührung mit der Kleinspannung hat.
Ist aber die Kleinspannungsseite vollständig isoliert und gegen Berührung geschützt, sollt der Verwendung eines Mini nichts entgegenstehen.
Außer dem Risiko für die Steuerungsseite der Kleinspannung durch eine Überschlag zerstört zu werden. Nutzerrisiko für den Ausfall des Torantriebs.
Jetzt dürft ihr mit DIN und VDE Normen werfen.

-
Erstmal in den Einstellungen zum Eingang von Schalter auf Taster umstellen. Dann sollten bei Aktionen oder Szenen auch die Tastereinstellungen verfügbar werden.
-
Hallo gibt es irgendwelche Erkenntnisse darüber, welchen Versorgungsspannungsbereich der Shelly1 im 12V Betrieb schadlos hinnimmt?
Also zb im KFZ Betrieb mit schwankender Versorgungsspannung von 11V bis 15V machbar?
Oder tötet das den Shelly1 ?
Plus oder Gen3 ist gemeint.
Meine Stichwortsuchen fanden nichts dazu.
Vielen Dank.
-
GuentherMeier wie sehen die Werte aus, wenn du oben rechts das Icon für "Net Metering" anklickst. Es sollte grün werden.
Standardmäßig zählt der 3em wohl Verbrauch und Einspeisung auf allen Phasen separat.
Mit Net Metering sollten eigentlich erst alle Phasenwerte addiert werden und dann nach Verbrauch oder Einspeisung klassifiziert. Das sollte dem Stromzählerwert des Energieversorgers entsprechen.