Hallo zusammen, ein kleines Tutorial zur Erstellung eines Somfy-Befehlssenders.
Funktionsweise:
Dieses Tutorial ermöglicht es Ihnen, einen 433,42-MHz-Sender zu erstellen, der über WLAN mit dem MQTT-Broker von Gladys verbunden ist, und Tasten zur Steuerung von Rollläden oder ähnlichen Systemen.
Sie können damit Markisen, Rollläden oder andere Systeme steuern, die nach dem Somfy-Steuerungsprinzip funktionieren.
Voraussetzungen
Sie benötigen:
- Eine ESP8266-Mini-Platine (oder eine andere, aber mit WLAN zur Netzwerkverbindung und 5V an den Pins)
- Einen 433-MHz-Sender mit kreisförmigem Resonator.
- Einen SAW-Filterresonator, Quarzkristall, 433,42 MHz, der .42 MHz ist sehr wichtig. Tatsächlich ist der Resonator der Sender nicht geeignet.
- Eine Federantenne
- Eine 5V-LED zur Bestätigung der Signalaussendung.
- Einige Anschlussdrähte.
- Ein Gehäuse, um alles unterzubringen. Sie haben die Wahl, aber nicht zu dick, um das Signal nicht zu blockieren.
- ein Lötkolben mit Lötzinn
Anschluss
Der schwierigste Schritt ist das Entfernen des Resonators am Sender, um seinen Ersatz zu löten.
Die blaue LED wird bei jedem Codeversand zwischen dem ESP8266 und dem Sender blinken. Kleine Überprüfung, um sicherzustellen, dass alles funktioniert!
Software-Seite:
- Arduino. Sie können es hier herunterladen:
- Fügen Sie die folgenden Bibliotheken hinzu:
- ESP8266WiFi.h
- EEPROM.h
- PubSubClient.h
- AsyncElegantOTA.h
Verbinden Sie Ihren ESP8266 und stellen Sie sicher, dass er erkannt wird.
Der Treiber für ESP8266-Kopien auf AliExpress kann hier gefunden werden:
Folgen Sie dem Installations-Tutorial.
In Arduino wählen Sie den COM-Port, der Ihrem kleinen Biest entspricht:
Wählen Sie Ihre Karte (Für Kopien von ESP8266-Karten verwende ich diese Kartenreferenz:
![]()
Programmierung
Damit die Gladys-Tasten die vom Sender erwarteten Werte senden können, müssen Sie mehrere MQTT-Fake-Geräte erstellen.
In der MQTT-Integration erstellen Sie 2 „Fake-Geräte“:
- Steuerung des Rollladens mit seinen 3 Tasten, die die Werte -1, 0 und 1 senden.
- Ein Dimmerschalter, der von 2 bis 6 inklusive aktiviert wird, um zu programmieren und die Codeschnittstelle zwischen der Rollladentaste und Ihrem Modul zu erstellen.
In Lien1 im Code angegeben
Sie können ein weiteres Fake-Textgerät erstellen, um in Gladys die Rückmeldung der vom Sender übernommenen Steuerung zu sehen. Das ist im Code vorgesehen, andernfalls lassen Sie es weg.
In Lien2 im Code angegeben
Stellen Sie sicher, dass Sie die Topic-Adressen abrufen, die Sie im Code für den ESP8266 angeben müssen.
Code:
Er enthält wahrscheinlich grobe Fehler, aber ich habe es geschafft, ihn mit meinen geringen Codierkenntnissen zum Laufen zu bringen. Er ist also sehr verbesserungsfähig .. ![]()
Ich bin nicht der Schöpfer des Codes, ich beanspruche daher auch nicht die Verdienste. Ich habe ihn nur angepasst, damit er Zahlenwerte statt Buchstaben akzeptiert.
2 = Down
3 = Stop
4 = Up
5 = Prog
6 =
Die 6 ist absichtlich leer gelassen, um die Programmierung mit dem Originalbefehl durchzuführen.
Wenn Sie mehrere Fernbedienungen erstellen möchten oder wenn Sie nach einer Änderung neu registrieren müssen, denken Sie daran, diesen Wert zu inkrementieren, wie im Beispiel für jeden der Sender angegeben: #define REMOTE 0x122000
/* Dieses Skript ermöglicht es Ihnen, eine Somfy RTS- oder Simu HZ-Fernbedienung zu emulieren.
Dies ist ein Fork des ursprünglichen Skripts, geschrieben von Nickduino (https://github.com/Nickduino)
Wenn Sie mehr über das Somfy RTS-Protokoll erfahren möchten, besuchen Sie https://pushstack.wordpress.com/somfy-rts-protocol/
Der Rollcode wird im EEPROM gespeichert, sodass Sie den D1 Mini mit Strom versorgen können.
Einfachste Methode, um es für Sie funktionieren zu lassen:
- Wählen Sie eine Fernbedienungsnummer
- Wählen Sie einen Startpunkt für den Rollcode. Jede unsigned int funktioniert, 1 ist ein guter Start
- Laden Sie das Skript hoch
- Drücken Sie lange den Programmierknopf IHRER ECHTEN FERNBEDEINUNG, bis Ihr Rollladen leicht auf und ab geht
- Senden Sie 'p' an das serielle Terminal oder über 'MQTT'
Um einen Gruppenbefehl zu machen, wiederholen Sie einfach die letzten beiden Schritte mit einem anderen Rollladen (einer nach dem anderen)
Dann:
- u wird es nach oben gehen lassen
- s wird es stoppen
- d wird es nach unten gehen lassen
- p setzt den Programmiermodus
- Sie können auch eine HEX-Zahl direkt für jeden seltsamen Befehl senden, den Sie (0x9 für den Sonnensensor zum Beispiel)
*/
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <AsyncElegantOTA.h>
WiFiClient espClient;
PubSubClient client(espClient);
String header;
const char* ssid = "xx"; // <-- Geben Sie Ihr WLAN-SSID ein
const char* password = "xx"; // <-- Geben Sie Ihr WLAN-Passwort ein
const char* mqtt_server = "xx"; // <-- Geben Sie die IP Ihres MQTT-Servers ein
const unsigned int mqtt_port = 1883;
const char* mqtt_user = "xx";
const char* mqtt_password = "xx"; // <-- Geben Sie das Passwort Ihres MQTT-Servers ein
String clientId = "Awning";
// MQTT-Topic-Parameter
const char* topic = "lien1"; // <-- Das Topic des Variators mit Code
const char* topic2 = "lien2"; // <-- Das Rückmeldungstext-Topic
#define SYMBOL 640
#define UP 0x2
#define STOP 0x1
#define DOWN 0x4
#define PROG 0x8
#define EEPROM_ADDRESS 0
#define REMOTE 0x121000 //<-- Ändern Sie dies in eine eindeutige Nummer, wenn Sie mehr als eine Fernbedienung haben (0x121305, 0x121306, 0x121307, ...)
AsyncWebServer server(80);
char demand = '6'; // w = wartend
const int transmitPin = D1;
unsigned long rollingCode = 1;
byte frame[7];
byte checksum;
void BuildFrame(byte *frame, byte button) {
unsigned int code;
EEPROM.get(EEPROM_ADDRESS, code);
frame[0] = 0xA7; // Verschlüsselungsschlüssel. Spielt nicht wirklich eine Rolle
frame[1] = button << 4; // Welche Taste haben Sie gedrückt? Die 4 LSB werden die Prüfsumme sein
frame[2] = code >> 8; // Rolling Code (Big Endian)
frame[3] = code; // Rolling Code
frame[4] = REMOTE >> 16; // Fernbedienungsadresse
frame[5] = REMOTE >> 8; // Fernbedienungsadresse
frame[6] = REMOTE; // Fernbedienungsadresse
Serial.print("Frame : ");
for(byte i = 0; i < 7; i++) {
if(frame[i] >> 4 == 0) { // Zeigt führende Nullen an, falls das höchstwertige
Serial.print("0"); // Nibble eine 0 ist.
}
Serial.print(frame[i],HEX); Serial.print(" ");
}
// Berechnung der Prüfsumme: ein XOR aller Nibbles
checksum = 0;
for(byte i = 0; i < 7; i++) {
checksum = checksum ^ frame[i] ^ (frame[i] >> 4);
}
checksum &= 0b1111; // Wir behalten nur die letzten 4 Bits
// Integration der Prüfsumme
frame[1] |= checksum; // Wenn ein XOR aller Nibbles gleich 0 ist, wird die Prüfsumme von den Jalousien
// als in Ordnung betrachtet.
Serial.println(""); Serial.print("Mit Prüfsumme : ");
for(byte i = 0; i < 7; i++) {
if(frame[i] >> 4 == 0) {
Serial.print("0");
}
Serial.print(frame[i],HEX); Serial.print(" ");
}
// Verschleierung: ein XOR aller Bytes
for(byte i = 1; i < 7; i++) {
frame[i] ^= frame[i-1];
}
Serial.println(""); Serial.print("Verschleiert : ");
for(byte i = 0; i < 7; i++) {
if(frame[i] >> 4 == 0) {
Serial.print("0");
}
Serial.print(frame[i],HEX); Serial.print(" ");
}
Serial.println("");
Serial.print("Rolling Code : "); Serial.println(code);
EEPROM.put(EEPROM_ADDRESS, code + 1); // Wir speichern den Wert des Rolling Codes im
// EEPROM. Es sollte bis zu 2 Adressen belegen, aber die
// Arduino-Funktion kümmert sich darum.
EEPROM.commit();
}
void SendCommand(byte *frame, byte sync) {
if(sync == 2) { // Nur mit dem ersten Frame.
// Aufweckimpuls & Stille
digitalWrite(transmitPin, HIGH);
delayMicroseconds(9415);
digitalWrite(transmitPin, LOW);
delayMicroseconds(89565);
}
// Hardware-Synchronisation: zwei Synchronisationen für den ersten Frame, sieben für die folgenden.
for (int i = 0; i < sync; i++) {
digitalWrite(transmitPin, HIGH);
delayMicroseconds(4*SYMBOL);
digitalWrite(transmitPin, LOW);
delayMicroseconds(4*SYMBOL);
}
// Software-Synchronisation
digitalWrite(transmitPin, HIGH);
delayMicroseconds(4550);
digitalWrite(transmitPin, LOW);
delayMicroseconds(SYMBOL);
// Daten: Bits werden einzeln gesendet, beginnend mit dem MSB.
for(byte i = 0; i < 56; i++) {
if(((frame[i/8] >> (7 - (i%8))) & 1) == 1) {
digitalWrite(transmitPin, LOW);
delayMicroseconds(SYMBOL);
digitalWrite(transmitPin, HIGH);
delayMicroseconds(SYMBOL);
}
else {
digitalWrite(transmitPin, HIGH);
delayMicroseconds(SYMBOL);
digitalWrite(transmitPin, LOW);
delayMicroseconds(SYMBOL);
}
}
digitalWrite(transmitPin, LOW);
delayMicroseconds(30415); // Zwischenrahmen-Stille
}
void callback(char* topic, byte* payload, unsigned int length) {
if (strcmp(topic,"lien1") == 0) {
char demand_str[length + 1];
strncpy (demand_str, (char*)payload, length);
demand_str[length] = '\0';
Serial.println(demand_str);
// u = hoch, d = runter, s = stop, p = programm, w = warten
if (strcmp(demand_str,"4") == 0) {
demand = '4';
} else if (strcmp(demand_str,"2") == 0) {
demand = '2';
} else if (strcmp(demand_str,"3") == 0) {
demand = '3';
} else if (strcmp(demand_str,"5") == 0) {
demand = '5';
} else {
demand = '6';
}
Serial.println(demand_str);
Serial.println(demand);
}
}
void setup() {
Serial.begin(115200);
Serial.println(" ");
Serial.println("Starting Somfy");
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
WiFi.hostname("Box-Somfy");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
pinMode(transmitPin, OUTPUT); // Pin D1 auf dem Wemos D1 mini
digitalWrite(transmitPin, LOW);
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "text/plain", "Hi! I am a Wemos D1 mini.");
});
AsyncElegantOTA.begin(&server); // Starte ElegantOTA
server.begin();
EEPROM.begin(4);
EEPROM.get(EEPROM_ADDRESS, rollingCode);
Serial.println(" ");
Serial.print("Simulierte Fernbedienungsnummer : ");
Serial.println(REMOTE, HEX);
Serial.print("Aktueller Rolling Code : ");
Serial.println(rollingCode);
}
void reconnect() {
// Schleife zum Verbinden mit dem MQTT-Broker
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
if (client.connect("WemosClient", mqtt_user, mqtt_password)) {
Serial.println("Connected to MQTT");
// Abonnement des MQTT-Topics
client.subscribe(topic);
} else {
Serial.print("Failed, rc=");
Serial.print(client.state());
Serial.println(" Retrying in 5 seconds...");
delay(5000);
}
}
}
void loop() {
AsyncElegantOTA.loop();
// Überprüfung der Verbindung zum MQTT-Broker
if (!client.connected()) {
reconnect();
}
// Aktualisierung des MQTT-Clients
client.loop();
if (demand == '4' || demand == '2' || demand == '3' || demand == '5') {
// char serie = (char)Serial.read();
char serie = (char)demand;
if(serie == '4') {
demand = '4';
Serial.println("up"); // Somfy ist schließlich ein französisches Unternehmen.
BuildFrame(frame, UP);
client.publish(topic2, "up");
delay(50);
client.subscribe(topic2);
Serial.println("moving up");
}
else if(serie == '2') {
demand = '2';
Serial.println("down");
BuildFrame(frame, DOWN);
client.publish(topic2, "down");
delay(50);
client.subscribe(topic2);
Serial.println("moving down");
}
else if(serie == '5') {
demand = '5';
Serial.println("prog");
BuildFrame(frame, PROG);
client.publish(topic2, "prog");
delay(50);
client.subscribe(topic2);
Serial.println("prog mode");
}
else if(serie == '3') {
demand = '3';
Serial.println("stop");
BuildFrame(frame, STOP);
client.publish(topic2, "stop");
delay(50);
client.subscribe(topic2);
Serial.println("stop");
}
demand = '6';
Serial.println("");
SendCommand(frame, 2);
for(int i = 0; i<2; i++) {
SendCommand(frame, 7);
}
}
}
Denken Sie daran, diese Werte entsprechend Ihrer eigenen Installation zu ändern:
• const char* ssid = « Ihr SSID-Netzwerkname »;
• const char* password = « Ihr WLAN-Code »;
• #define MQTT_BROKER « Broker-IP-Adresse »
• #define MQTT_BROKER_PORT 1883
• #define MQTT_USERNAME « MQTT-Broker-Benutzername »
• #define MQTT_KEY « Broker-Passwort »
Wenn Sie diesen Code für mehrere Module mit demselben MQTT-Broker verwenden, denken Sie daran, diesen Wert im Abschnitt « void reconnect » zu ändern:
if (client.connect(« WemosClient2 », mqtt_user, mqtt_password)) {
Gladys-Szenen:
Schließlich, um mit dem neuen Gladys-Alarmsystem zu funktionieren, müssen Sie 3 Szenen für die Rollladensteuerung auf Basis dieser erstellen:
Rollladen herunter: -1 → 2
Gleiches für Stop: 0 → 3
Gleiches für Hoch: 1 → 4
Registrierung des neuen Moduls am Rollladen.
Letzter Schritt, den Rollladen in den Modus zur Registrierung einer neuen Fernbedienung versetzen. Sie sollten auf Ihrer Fernbedienung einen Programmierknopf haben, den Sie einige Sekunden lang drücken müssen. Der Rollladen sollte sich leicht auf und ab bewegen, um dies zu bestätigen.
In Gladys, stellen Sie den Dimmer auf 5. Der Rollladen sollte reagieren und die Bewegung wiederholen.
Wenn ja, dann ist es erledigt ![]()
Wenn nicht, versuchen Sie es erneut, indem Sie den Dimmer auf 6 und dann auf 5 umschalten. Es kann vorkommen, dass Sie den Code ändern müssen, damit der Rollladen dies als neue Fernbedienung interpretiert.
Der Rollladen verlässt den Fernbedienungsregistrierungsmodus von selbst.
Viel Erfolg.
Tiboys


















