Hi,
Wanted to share a full scene open / close system for blinds. Mixing various remotes & zwave devices.
My scene.yaml :
- name: open_all_blinds
entities:
cover.somfy_blinds: "open"
cover.frontdoor_blinds: "open"
cover.small_shutter_level: "open"
cover.small_shutter_switch: "open"
cover.big_shutter_level: "open"
icon: mdi:blinds-open
- name: close_all_blinds
entities:
cover.somfy_blinds: "closed"
cover.frontdoor_blinds: "closed"
cover.small_shutter_level: "closed"
cover.big_shutter_level: "closed"
icon: mdi:blinds
My frontend integration:
type: horizontal-stack
cards:
- type: button
tap_action:
action: call-service
service: scene.turn_on
service_data:
entity_id: scene.open_all_blinds
entity: scene.open_all_blinds
name: Open blinds
icon: 'mdi:blinds-open'
- type: button
tap_action:
action: call-service
service: scene.turn_on
service_data:
entity_id: scene.close_all_blinds
entity: scene.close_all_blinds
name: Close blinds
icon: 'mdi:blinds'
The Home assistant config:
- platform: mqtt
name: "Somfy Blinds"
command_topic: "homeassistant/ESP-Somfy/cmd"
state_topic: "homeassistant/ESP-Somfy/state"
availability_topic: "homeassistant/ESP-Somfy/status"
qos: 0
retain: false
payload_open: "OPEN"
payload_close: "CLOSE"
state_open: "open"
state_closed: "closed"
payload_available: "online"
payload_not_available: "offline"
Btw, if you are interested with the smart remote, my Somfy telis 4 is linked to an ESP8266. The remote buttons are just putting the left part of the push button to the GND (right). So basically, pressing the button just put it to the Ground. Wire the part that is not GND to any I/O port of the ESP8266, the GND of the remote to GND of ESP8266 and VCC to VCC. I used this wiring diagram. The Arduino code is a mashup I made based on several source code and some of mine:
#include <PubSubClient.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <EEPROM.h>
#ifdef ESP32
#include <WiFi.h>
#elif ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef ESP32
#include <ESPmDNS.h>
#elif ESP8266
#include <ESP8266mDNS.h>
#endif
int OTAport = 8266;
const char* OTApassword = "xxxxxxx";
uint8_t OPEN = 2;
uint8_t STOP = 0;
uint8_t CLOSE = 4;
const char* cmd_topic = "homeassistant/ESP-Somfy/cmd";
const char* state_topic = "homeassistant/ESP-Somfy/state";
const char* status_topic = "homeassistant/ESP-Somfy/status";
const char* wifi_ssid = "xxxxxx";
const char* wifi_password = "xxxxxxxxx";
const unsigned int mqtt_port = 1883;
const char* mqtt_id = "ESP1";
const char* device_name = "ESP-Somfy";
long tps = 0;
long i = 0;
const char* mqtt_server = "xxxxx";
const char* mqtt_user = "xxxxxxx";
const char* mqtt_password = "xxxxxxxx";
String state_shutter;
void Wifi_init();
void OTA_init();
void Button_press(char* button);
void mqttconnect();
void receivedCallback(char* topic, byte* payload, unsigned int length);
void EEwrite(char add,String data);
String EEread(char add);
WiFiClient wifiClient;
PubSubClient client(wifiClient);
void Wifi_init()
{
long logrssi = 0 ;
if (WiFi.SSID() != wifi_ssid)
{
Serial.printf("[Connecting to %s ]\n", wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_password);
Serial.printf("[");
WiFi.persistent(true);
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(true);
}
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(1000);
}
Serial.println("]");
for (size_t i = 0; i < 10; i++)
{
long rssi = WiFi.RSSI();
logrssi = logrssi + rssi;
delay(200);
}
#ifdef ESP32
WiFi.setHostname(device_name);
#elif ESP8266
WiFi.hostname(device_name);
#endif
Serial.printf("[MAC: %s IP: %s]\n", WiFi.macAddress().c_str(),
WiFi.localIP().toString().c_str());
Serial.printf("[Mean rssi = %0.1d dBm ]\n", logrssi / 10);
delay(1000);
}
void OTA_init()
{
ArduinoOTA.setPort(OTAport);
ArduinoOTA.setHostname(device_name);
ArduinoOTA.setPassword((const char *)OTApassword);
ArduinoOTA.onStart([]() { Serial.println("Starting"); });
ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); });
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); });
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
void EEwrite(char add,String data)
{
int _size = data.length();
int i;
for(i=0;i<_size;i++)
{
EEPROM.write(add+i,data[i]);
}
EEPROM.write(add+_size,'\0'); //Add termination null character for String Data
EEPROM.commit();
}
String EEread(char add)
{
char data[10]; //Max 10 Bytes
int i=0;
unsigned char k;
k=EEPROM.read(add);
for(i=0;i<9;i++)
{
k=EEPROM.read(add+i);
data[i]=k;
i++;
}
data[i]='\0';
return String(data);
}
void mqttconnect() {
while ( !client.connected() ) {
Serial.print("[Connecting to MQTT server: ");
if (client.connect(mqtt_id, mqtt_user, mqtt_password, status_topic, 1, 1, "offline", 1)) {
Serial.println("connected ]");
client.subscribe(cmd_topic, 1);
Serial.println("[Subscribed to cmd topics ]");
client.publish(status_topic, "online", false);
}
else {
Serial.print("*** MQTT broker connexion failed, status code=");
Serial.print(client.state());
Serial.print(" ***");
Serial.println("[Retrying in 5 seconds]");
delay(5000);
}
}
}
void receivedCallback(char* topic, byte* payload, unsigned int length) {
payload[length]='\0';
if(strcmp((char *)payload, "OPEN") == 0) {
Serial.println("- Shutter up cmd received");
Button_press(OPEN);
state_shutter = "open";
EEwrite(0,state_shutter);
}
if(strcmp((char *)payload, "STOP") == 0) {
Serial.println("- Shutter stop cmd received");
Button_press(STOP);
state_shutter = "unkown";
EEwrite(0,state_shutter);
}
if(strcmp((char *)payload, "CLOSE") == 0) {
Serial.print("- Shutter down cmd received");
Serial.println("off");
Button_press(CLOSE);
state_shutter = "closed";
EEwrite(0,state_shutter);
}
client.publish(state_topic, state_shutter.c_str(), false);
}
void Button_press(uint8_t button) {
Serial.print("-- Pressing button: ");
Serial.println(button);
digitalWrite(button,LOW);
delay(1000);
Serial.println("-- Releasing button");
digitalWrite(button, HIGH);
}
void setup()
{
String previous_state;
Serial.begin(115200);
Serial.printf("[<<<<<<<<<Booting up %s>>>>>>>>>>]\n", device_name);
Wifi_init();
Serial.println("[Setting up I/O ]");
pinMode(OPEN,OUTPUT);
pinMode(STOP,OUTPUT);
pinMode(CLOSE,OUTPUT);
digitalWrite(OPEN,HIGH); // Set IN and OUT HIGH so the remote doesn't activate on start IN
digitalWrite(STOP,HIGH);
digitalWrite(CLOSE,HIGH);
Serial.println("[Setting up OTA ]");
OTA_init();
Serial.println("[Setting up MQTT ]");
client.setKeepAlive(60);
client.setServer(mqtt_server, mqtt_port);
client.setCallback(receivedCallback);
Serial.println("[Getting state pre-reboot from EEPROM ]");
EEPROM.begin(10);
previous_state = EEread(0);
Serial.println("[Connecting to MQTT ]");
mqttconnect();
delay(2000);
if ( client.connected() ) {
Serial.println("[Updating MQTT with pre-reboot state ]");
client.publish(state_topic, previous_state.c_str(), false);
}
Serial.println("[<<<<<<Init completed successfully>>>>>>]");
}
void loop()
{
ArduinoOTA.handle();
if (WiFi.status() != WL_CONNECTED) {
Serial.println("*** Wifi disconnected: reconnecting ***");
Wifi_init();
}
if ( !client.connected() ) {
Serial.println("*** MQTT disconnected: reconnecting ***");
mqttconnect();
}
client.loop();
delay(200);
if (millis()-tps>55000){
tps=millis();
client.publish(status_topic, "online", false);
}