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.
#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();
}