# Nora/Google Blinds Node Integration with Home Assistant and MQTT

**URL:** https://discourse.nodered.org/t/nora-google-blinds-node-integration-with-home-assistant-and-mqtt/37162
**Category:** General
**Created:** [8 December 2020 04:06 UTC](https://discourse.nodered.org/t/nora-google-blinds-node-integration-with-home-assistant-and-mqtt/37162 "2020-12-08T04:06:07Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![kevinfuller](https://avatars.discourse-cdn.com/v4/letter/k/b77776/32.png) [@kevinfuller](https://discourse.nodered.org/u/kevinfuller)
#### Post date: [8 December 2020 04:06 UTC](https://discourse.nodered.org/t/nora-google-blinds-node-integration-with-home-assistant-and-mqtt/37162/1 "2020-12-08T04:06:07Z")

</div>

HI, I am new to this forum and I am hoping to get some help. I recently started a project to automate window blinds using MQTT. I can control the blinds from a phone app that connects to my MQTT server and I have integrated Home Assistant with Google using Node Red and the NORA Blinds node and everything seems to be communicating.

My problem is that when I tell Google to open or close the blinds it sends the message {"openPercent":100} or {"openPercent":0} respectively. I understand that is what it is supposed to do. However, that is not what the MQTT client is looking for and, subsequently, it sees the string as a 0. If my blinds integer is set to anything other than a 0 then they will move to the 0 position but they will not move by voice after that because all it sees is a zero unless I change it.

I have tried changing the message to an integer but nothing seems to work. Can anyone help me get this to work? Below is an example of my Node Red sequence and the code I am using for the blinds ESP8266. I did not write this code and don't claim to completely understand it so please be patient with this non-coder trying to learn. Any help would be extremely appreciated.

 ![Blinds Node Red Sequence](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/d/2dd79afb9a65deb270cc1ac52cded7cd1de8e3ad.jpeg)

```auto
#define USER_SSID ""
#define USER_PASSWORD ""
#define USER_MQTT_SERVER ""
#define USER_MQTT_PORT            
#define USER_MQTT_USERNAME ""
#define USER_MQTT_PASSWORD ""
#define USER_MQTT_CLIENT_NAME "" // Used to define MQTT topics, MQTT Client ID, and ArduinoOTA

#define STEPPER_SPEED 15 //Defines the speed in RPM for your stepper motor
#define STEPPER_STEPS_PER_REV 1028 //Defines the number of pulses that is required for the stepper to rotate 360 degrees
#define STEPPER_MICROSTEPPING 0 //Defines microstepping 0 = no microstepping, 1 = 1/2 stepping, 2 = 1/4 stepping 
#define DRIVER_INVERTED_SLEEP 1 //Defines sleep while pin high. If your motor will not rotate freely when on boot, comment this line out.

#define STEPS_TO_CLOSE 12 //Defines the number of steps needed to open or close fully

#define STEPPER_DIR_PIN D3
#define STEPPER_STEP_PIN D4
#define STEPPER_SLEEP_PIN D8
#define STEPPER_MICROSTEP_1_PIN 14
#define STEPPER_MICROSTEP_2_PIN 12
 
/ *****************END USER CONFIG SECTION******************************* /
/ *****************END USER CONFIG SECTION******************************* /
/ *****************END USER CONFIG SECTION******************************* /
/ *****************END USER CONFIG SECTION******************************* /
/ *****************END USER CONFIG SECTION******************************* /

WiFiClient espClient;
PubSubClient client(espClient);
SimpleTimer timer;
AH_EasyDriver shadeStepper(STEPPER_STEPS_PER_REV, STEPPER_DIR_PIN ,STEPPER_STEP_PIN,STEPPER_MICROSTEP_1_PIN,STEPPER_MICROSTEP_2_PIN,STEPPER_SLEEP_PIN);

//Global Variables
bool boot = true;
int currentPosition = 0;
int newPosition = 0;
char positionPublish[50];
bool moving = false;
char charPayload[50];

const char* ssid = USER_SSID ; 
const char* password = USER_PASSWORD ;
const char* mqtt_server = USER_MQTT_SERVER ;
const int mqtt_port = USER_MQTT_PORT ;
const char *mqtt_user = USER_MQTT_USERNAME ;
const char *mqtt_pass = USER_MQTT_PASSWORD ;
const char *mqtt_client_name = USER_MQTT_CLIENT_NAME ; 

//Functions
void setup_wifi() {
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);  
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() 
{
  int retries = 0;
  while (!client.connected()) {
    if(retries < 150)
    {
      Serial.print("Attempting MQTT connection...");
      if (client.connect(mqtt_client_name, mqtt_user, mqtt_pass)) 
      {
        Serial.println("connected");
        if(boot == false)
        {
          client.publish(USER_MQTT_CLIENT_NAME"/checkIn","Reconnected"); 
        }
        if(boot == true)
        {
          client.publish(USER_MQTT_CLIENT_NAME"/checkIn","Rebooted");
        }
        // ... and resubscribe
        client.subscribe(USER_MQTT_CLIENT_NAME"/blindsCommand");
        client.subscribe(USER_MQTT_CLIENT_NAME"/positionCommand");
      } 
      else 
      {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        retries++;
        // Wait 5 seconds before retrying
        delay(5000);
      }
    }
    if(retries > 149)
    {
    ESP.restart();
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) 
{
  Serial.print("Message arrived [");
  String newTopic = topic;
  Serial.print(topic);
  Serial.print("] ");
  payload[length] = '\0';
  String newPayload = String((char *)payload);
  int intPayload = newPayload.toInt();
  Serial.println(newPayload);
  Serial.println();
  newPayload.toCharArray(charPayload, newPayload.length() + 1);
  if (newTopic == USER_MQTT_CLIENT_NAME"/blindsCommand") 
  {
    if (newPayload == "OPEN")
    {
      client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", "0", true);
    }
    else if (newPayload == "CLOSE")
    {   
      int stepsToClose = STEPS_TO_CLOSE;
      String temp_str = String(stepsToClose);
      temp_str.toCharArray(charPayload, temp_str.length() + 1);
      client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", charPayload, true);
    }
    else if (newPayload == "STOP")
    {
      String temp_str = String(currentPosition);
      temp_str.toCharArray(positionPublish, temp_str.length() + 1);
      client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", positionPublish, true); 
    }
  }
  if (newTopic == USER_MQTT_CLIENT_NAME"/positionCommand")
  {
    if(boot == true)
    {
      newPosition = intPayload;
      currentPosition = intPayload;
      boot = false;
    }
    if(boot == false)
    {
      newPosition = intPayload;
    }
  }
  
}

void processStepper()
{
  if (newPosition > currentPosition)
  {
    #if DRIVER_INVERTED_SLEEP == 1
    shadeStepper.sleepON();
    #endif
    #if DRIVER_INVERTED_SLEEP == 0
    shadeStepper.sleepOFF();
    #endif
    shadeStepper.move(80, FORWARD);
    currentPosition++;
    moving = true;
  }
  if (newPosition < currentPosition)
  {
    #if DRIVER_INVERTED_SLEEP == 1
    shadeStepper.sleepON();
    #endif
    #if DRIVER_INVERTED_SLEEP == 0
    shadeStepper.sleepOFF();
    #endif
    shadeStepper.move(80, BACKWARD);
    currentPosition--;
    moving = true;
  }
  if (newPosition == currentPosition && moving == true)
  {
    #if DRIVER_INVERTED_SLEEP == 1
    shadeStepper.sleepOFF();
    #endif
    #if DRIVER_INVERTED_SLEEP == 0
    shadeStepper.sleepON();
    #endif
    String temp_str = String(currentPosition);
    temp_str.toCharArray(positionPublish, temp_str.length() + 1);
    client.publish(USER_MQTT_CLIENT_NAME"/positionState", positionPublish); 
    moving = false;
  }
  Serial.println(currentPosition);
  Serial.println(newPosition);
}

void checkIn()
{
  client.publish(USER_MQTT_CLIENT_NAME"/checkIn","OK"); 
}

//Run once setup
void setup() {
  Serial.begin(115200);
  shadeStepper.setMicrostepping(STEPPER_MICROSTEPPING); // 0 -> Full Step                                
  shadeStepper.setSpeedRPM(STEPPER_SPEED); // set speed in RPM, rotations per minute
  #if DRIVER_INVERTED_SLEEP == 1
  shadeStepper.sleepOFF();
  #endif
  #if DRIVER_INVERTED_SLEEP == 0
  shadeStepper.sleepON();
  #endif
  WiFi.mode(WIFI_STA);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  ArduinoOTA.setHostname(USER_MQTT_CLIENT_NAME);
  ArduinoOTA.begin(); 
  delay(10);
  timer.setInterval(((1 << STEPPER_MICROSTEPPING)*5800)/STEPPER_SPEED, processStepper);   
  timer.setInterval(90000, checkIn);
}

void loop() 
{
  if (!client.connected()) 
  {
    reconnect();
  }
  client.loop();
  ArduinoOTA.handle();
  timer.run();
}

```

---

<div class="post-metadata">

### Author: ![rgerrans](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@rgerrans](https://discourse.nodered.org/u/rgerrans)
#### Post date: [9 December 2020 19:38 UTC](https://discourse.nodered.org/t/nora-google-blinds-node-integration-with-home-assistant-and-mqtt/37162/2 "2020-12-09T19:38:57Z")

</div>

> [@kevinfuller](#):
>
> My problem is that when I tell Google to open or close the blinds it sends the message {"openPercent":100} or {"openPercent":0} respectively. I understand that is what it is supposed to do. However, that is not what the MQTT client is looking for and, subsequently, it sees the string as a 0. If my blinds integer is set to anything other than a 0 then they will move to the 0 position but they will not move by voice after that because all it sees is a zero unless I change it.

You need to use a Change node to set the msg.payload equal to the openPercent.

---

<div class="post-metadata">

### Author: ![kevinfuller](https://avatars.discourse-cdn.com/v4/letter/k/b77776/32.png) [@kevinfuller](https://discourse.nodered.org/u/kevinfuller)
#### Post date: [10 December 2020 04:06 UTC](https://discourse.nodered.org/t/nora-google-blinds-node-integration-with-home-assistant-and-mqtt/37162/3 "2020-12-10T04:06:15Z")

</div>

Thanks, Ron. I have been trying to use the Change node but it seems nothing I put in the fields makes a difference. Can you help with the syntax?

[Debug|690x464](https://discourse.nodered.org/uploads/short-url/l33ZAsrjjn7ujcD25BXtdvh1wsx.jpeg)

---

<div class="post-metadata">

### Author: ![rgerrans](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@rgerrans](https://discourse.nodered.org/u/rgerrans)
#### Post date: [10 December 2020 04:35 UTC](https://discourse.nodered.org/t/nora-google-blinds-node-integration-with-home-assistant-and-mqtt/37162/4 "2020-12-10T04:35:32Z")

</div>

Here you go:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/6/16a68a4a03dcd68a221a0f3d203cc0f17236e7c8.png)

---

<div class="post-metadata">

### Author: ![kevinfuller](https://avatars.discourse-cdn.com/v4/letter/k/b77776/32.png) [@kevinfuller](https://discourse.nodered.org/u/kevinfuller)
#### Post date: [10 December 2020 06:09 UTC](https://discourse.nodered.org/t/nora-google-blinds-node-integration-with-home-assistant-and-mqtt/37162/5 "2020-12-10T06:09:57Z")

</div>

Ron!!!! You are my savior! That worked. Thank you so much for your help!!!!

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [8 February 2021 06:10 UTC](https://discourse.nodered.org/t/nora-google-blinds-node-integration-with-home-assistant-and-mqtt/37162/6 "2021-02-08T06:10:04Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
