MQTT based Leinwand Remote Control

I wanted to make my motorized canvas MQTT-enabled so that it can be embedded into greater automation scenes. 

For this I have taken an ESP8266 controller and attached some (left over) relais to it. The yellow cables attach them to the original wireless sender board which talks to the motorized canvas.

After connecting to my MQTT bus a GPIO is set HIGH which provides sufficient 3V to power the sender board. My automation is now able to lower the canvas, the beamer from the ceiling lift and ignite and configure the beamer. Interesting use case is the „cinema mode“ which lowers the canvas, beamer hidden in the ceiling, start the beamer including FireTv stick and set the beamer settings to cinema mode like set HDR=ON, activate 4K and activate a special color profile.

// MQTT commands are as easy as:
sensors/leinwand/action/up
sensors/leinwand/action/down
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid     = "_REMOVED_";
const char* password = "_REMOVED_";
const char* mqtt_server = "mqtt";
char clientRSSI[50];

const int PIN_UP = 12;
const int PIN_DOWN = 14;
const int PIN_REMOTE = 13;
const int PIN_WIFI_LED = 3;

void callback(char* topic, byte* payload, unsigned int length);

WiFiClient espClient;
PubSubClient client(mqtt_server, 1883, callback, espClient);

void callback(char* topic, byte* payload, unsigned int length) {
    
    if(strcmp(topic, "sensors/leinwand/action/up") == 0) {
      digitalWrite(PIN_UP, HIGH);
      delay(1000);
      digitalWrite(PIN_UP, LOW);
      client.publish("sensors/leinwand/up","");
    }

    if(strcmp(topic, "sensors/leinwand/action/down") == 0) {
      digitalWrite(PIN_DOWN, HIGH);
      delay(1000);
      digitalWrite(PIN_DOWN, LOW);
      client.publish("sensors/leinwand/down","");
    }
}

void reconnectWifi() {
    WiFi.begin(ssid, password); 
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
    }
    String str = String(WiFi.RSSI());
    str.toCharArray(clientRSSI, str.length()+1);
}

void reconnectMQTT() {
  
  while (!client.connected()) {
   
    if (client.connect("leinwand","sensors/leinwand/health", 0, true, "offline")) {
      client.setCallback(callback);      

      client.publish("sensors/leinwand/rssi", clientRSSI, true);
      client.publish("sensors/leinwand", "started", true);
      client.publish("sensors/leinwand/health", "online", true);
      client.subscribe("sensors/leinwand/action/#");

      digitalWrite(PIN_REMOTE, HIGH);
      digitalWrite(PIN_WIFI_LED, HIGH);
    
    } else {
      delay(1000);
    }
  }
}

void setup() {
  Serial.begin(115200);

  pinMode(PIN_REMOTE, OUTPUT);
  pinMode(PIN_UP, OUTPUT);
  pinMode(PIN_DOWN, OUTPUT);
  pinMode(PIN_WIFI_LED, OUTPUT);  

  digitalWrite(PIN_REMOTE, LOW);
  digitalWrite(PIN_UP, LOW);
  digitalWrite(PIN_DOWN, LOW);
  digitalWrite(PIN_WIFI_LED, LOW);
}

void loop() {

  if(WiFi.status() != WL_CONNECTED) {
    digitalWrite(PIN_WIFI_LED, LOW);
    reconnectWifi();
  }
 
  if (!client.connected()) {
    digitalWrite(PIN_WIFI_LED, LOW);
    reconnectMQTT();
  }

  client.loop();
}