@jjhtpc He! Thanks! I’m trying to set this up with a continues servo. Do you perhaps still have the original sketch from BRUH? His link is offline, i’d really like this.
Hi jjhtpc,
Do you think it is possible to shut off the wifi on the esp8266 since we are using only the mqtt to control the blind. I am thinking to connect it to a solar power panel that is charging the battery.
MQTT is just Message Queue Telemetry Transport and that transport is still occurring over wifi. The wifi connection is still needed.
The only thing that I borrowed from BRUH on this was the MQTT configuration. I think there were others that were using continuous rotation though. I know that I had created my blinds originally on Smarttings with a Spark Core chip and there were definitely people that adapted my code to continuous rotation. You could look over there.
Thanks for your reply, i’ve been tinkering around, cursing, smashing, but i got it, with continuous rotation. I have 50/50 curtains. So just have to figure out the time needed to open/close
Anyone intergrated OTA? Can’t seem to get it working. (webserver or just Arduino IDE)
Just follow the guide to make the servo a continuous one:
Then i’ve used this code:
#include <PubSubClient.h>
#include <Servo.h>
#include <WiFiClientSecure.h>
#include <ESP8266WiFiAP.h>
#include <WiFiUdp.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WiFiSTA.h>
#include <ESP8266WiFiGeneric.h>
#include <ESP8266WiFi.h>
#include <WiFiServer.h>
#include <ESP8266WiFiScan.h>
#include <WiFiClient.h>
#include <ESP8266WiFiType.h>
#define wifi_ssid "<input here>"
#define wifi_password "<input here>8"
#define mqtt_server "<input here>"
#define mqtt_user "<input here>"
#define mqtt_password "<input here>"
WiFiClient espClient;
PubSubClient client(espClient);
Servo myservo;
int val;
int itsatrap = 0;
void setup() {
Serial.begin(9600);
setup_wifi();
client.setServer(mqtt_server, 1883); //CHANGE PORT HERE IF NEEDED
client.setCallback(callback);
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_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 callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
String mytopic(topic);
if (itsatrap == 0 && mytopic == "blinds/back/cmnd" && message.equals("ON")){
myservo.attach(D4); // make sure to use pin D4, or change it
delay(500);
myservo.write(180); // this makes the servo rotate in one direction for 6 seconds
client.publish("blinds/back/state", "ON");
delay(6000);
myservo.detach();
}
else if (mytopic == "blinds/back/cmnd" && message.equalsIgnoreCase("OFF")){
myservo.attach(D4); // make sure to use pin D4, or change it
delay(500);
myservo.write(0);
client.publish("blinds/back/state", "OFF");
delay(6000); // this makes the servo rotate the other direction for 6 seconds
myservo.detach();
}
else{
itsatrap = 0;
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESPBlindstl", mqtt_user, mqtt_password)) {
Serial.println("connected");
client.subscribe("blinds/back/cmnd");
client.publish("blinds/back/state", "OFF");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
Where you have a state topic:
blinds/back/state
Where you can read the state eg. ON/OFF (hass sensor open/closed)
And a command topic:
blinds/back/cmnd
Where you can command ON (one way) and OFF (the other)
If you have multiple (like me, around 7) just change every ‘back’ to the device corresponding on every flash.
Edit:
I have this MQTT cover setup:
cover:
- platform: mqtt
name: "Ground floor back"
command_topic: "blinds/back/cmnd"
state_topic: "blinds/back/state"
qos: 2
retain: false
payload_open: "ON"
payload_close: "OFF"
state_open: "open"
state_closed: "closed"
optimistic: false
I have tried to use a solar panel to charge my power bank and at the same time to power the esp8266 with s3003. Its not capable of powering the servo but the esp8266 is up and running. Any idea what i can do? Or is there a servo that i can use which draw less current?
It is not the servo. It is the wifi chip on the 8266. I have not found a solar solution that works even with deep sleep, but deep sleep kind of goes against the concept of automation. I ran USB in my walls, this way you don’t see wires and you always have proper power.
I need help with my code. Could somebody check my code for mistakes?
HA config
light:
- platform: mqtt
name: "Window Bottom Center"
state_topic: "blind/bc/state"
command_topic: "blind/bc/command"
brightness_state_topic: "blind/bc/state"
brightness_command_topic: "blind/bc/level"
brightness_scale: 100
qos: 0
payload_on: "ON"
payload_off: "OFF"
optimistic: false
retain: true
Arduino code
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/************ WIFI and MQTT INFORMATION (CHANGE THESE FOR YOUR SETUP) ******************/
#define wifi_ssid "Kalaverkko" //enter your WIFI SSID
#define wifi_password "qwerty12" //enter your WIFI Password
#define mqtt_server "192.168.1.147" // Enter your MQTT server adderss or IP. I use my DuckDNS adddress (yourname.duckdns.org) in this field
#define mqtt_user "mqttadmin" //enter your MQTT username
#define mqtt_password "qwerty12" //enter your password
WiFiClient espClient;
PubSubClient client(espClient);
Servo myservo;
int val;
int itsatrap = 0;
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883); //CHANGE PORT HERE IF NEEDED
client.setCallback(callback);
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_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 callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
String mytopic(topic);
if (itsatrap == 0 && mytopic == "blind/bc/command" && message.equals("ON")){
myservo.attach(D4);
delay(500);
myservo.write(90);
client.publish("blind/bc/state", "ON");
delay(1000);
myservo.detach();
}
else if (mytopic == "blind/bc/command" && message.equalsIgnoreCase("OFF")){
myservo.attach(D4);
delay(500);
myservo.write(0);
client.publish("blind/bc/state", "OFF");
delay(1000);
myservo.detach();
}
else if (mytopic == "blind/bc/level"){
myservo.attach(D4);
delay(500);
val = message.toInt(); //converts command to integer to be used for positional arrangement
val = map (val, 0, 99, 0, 180);
myservo.write(val);
client.publish("blind/bc/state", "ON");
delay(3000);
myservo.detach();
itsatrap = 1;
}
else{
itsatrap = 0;
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP_blind", mqtt_user, mqtt_password)) {
Serial.println("connected");
client.subscribe("blind/bc/command");
client.subscribe("blind/bc/level");
client.publish("blind/bc/state", "OFF");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
MQTT log
1554224006: New connection from 192.168.1.248 on port 1883. 1554224006: |-- mosquitto_auth_unpwd_check(mqttadmin) 1554224006: |-- ** checking backend http 1554224006: |-- url=http://127.0.0.1:8080/login 1554224006: |-- data=username=mqttadmin&password=qwerty12&topic=&acc=-1&clientid= [INFO] found mqttadmin on local database 1554224008: |-- getuser(mqttadmin) AUTHENTICATED=1 by http 1554224008: New client connected from 192.168.1.248 as ESP_blind (c1, k15, u'mqttadmin'). 1554224008: |-- mosquitto_auth_acl_check(..., client id not available, mqttadmin, blind/bc/command, MOSQ_ACL_WRITE) 1554224008: |-- aclcheck(mqttadmin, blind/bc/command, 4) CACHEDAUTH: 0 1554224008: |-- mosquitto_auth_acl_check(..., client id not available, mqttadmin, blind/bc/level, MOSQ_ACL_WRITE) 1554224008: |-- aclcheck(mqttadmin, blind/bc/level, 4) CACHEDAUTH: 0 1554224008: |-- mosquitto_auth_acl_check(..., client id not available, mqttadmin, blind/bc/state, MOSQ_ACL_WRITE) 1554224008: |-- aclcheck(mqttadmin, blind/bc/state, 2) CACHEDAUTH: 0
Solved. My MQTT settings were not correct. I’m a total noob with home assistant and MQTT but I’m learning every day.
Did your code work?
I’m just getting started with a stepper.
Hi
Yes I got it working. I ended up using code from here https://github.com/thehookup/MQTT_Motorized_Shades
Since then I have moved to geared DC motor because my roller shade was too heavy for the stepper motor and it was making aloud noise in every rotation.
Hi,
I followed the instructions, but the HA log shows the following error. I appreciate any help:
2020-12-31 13:25:20 ERROR (MainThread) [homeassistant.util.logging] Exception in brightness_received when handling msg on 'blind/bc/state': 'ON'
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/mqtt/debug_info.py", line 35, in wrapper
msg_callback(msg)
File "/usr/src/homeassistant/homeassistant/components/mqtt/light/schema_basic.py", line 340, in brightness_received
device_value = float(payload)
ValueError: could not convert string to float: 'ON'
2020-12-31 13:25:48 ERROR (MainThread) [homeassistant.util.logging] Exception in brightness_received when handling msg on 'blind/bc/state': 'OFF'
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/mqtt/debug_info.py", line 35, in wrapper
msg_callback(msg)
File "/usr/src/homeassistant/homeassistant/components/mqtt/light/schema_basic.py", line 340, in brightness_received
device_value = float(payload)
ValueError: could not convert string to float: 'OFF'
This is the parameter I have configured:
#include <Servo.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiAP.h>
#include <ESP8266WiFiGeneric.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WiFiScan.h>
#include <ESP8266WiFiSTA.h>
#include <ESP8266WiFiType.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
/************ WIFI and MQTT INFORMATION (CHANGE THESE FOR YOUR SETUP) ******************/
#define wifi_ssid "*****" //enter your WIFI SSID
#define wifi_password "*****" //enter your WIFI Password
#define mqtt_server "******" // Enter your MQTT server adderss or IP. I use my DuckDNS adddress (yourname.duckdns.org) in this field
#define mqtt_user "******" //enter your MQTT username
#define mqtt_password "******" //enter your password
WiFiClient espClient;
PubSubClient client(espClient);
Servo myservo;
int val;
int itsatrap = 0;
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883); //CHANGE PORT HERE IF NEEDED
client.setCallback(callback);
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_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 callback(char* topic, byte* payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
String mytopic(topic);
if (itsatrap == 0 && mytopic == "blind/bc/command" && message.equals("ON")){
myservo.attach(D4);
delay(500);
myservo.write(90);
client.publish("blind/bc/state", "ON");
delay(1000);
myservo.detach();
}
else if (mytopic == "blind/bc/command" && message.equalsIgnoreCase("OFF")){
myservo.attach(D4);
delay(500);
myservo.write(0);
client.publish("blind/bc/state", "OFF");
delay(1000);
myservo.detach();
}
else if (mytopic == "blind/bc/level"){
myservo.attach(D4);
delay(500);
val = message.toInt(); //converts command to integer to be used for positional arrangement
val = map (val, 0, 99, 0, 180);
myservo.write(val);
client.publish("blind/bc/state", "ON");
delay(3000);
myservo.detach();
itsatrap = 1;
}
else{
itsatrap = 0;
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESPBlindstl", mqtt_user, mqtt_password)) {
Serial.println("connected");
client.subscribe("blind/bc/command");
client.subscribe("blind/bc/level");
client.publish("blind/bc/state", "OFF");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
Config HA:
light:
- platform: mqtt
name: "Window Bottom Center"
state_topic: "blind/bc/state"
command_topic: "blind/bc/command"
brightness_state_topic: "blind/bc/state"
brightness_command_topic: "blind/bc/level"
brightness_scale: 100
qos: 0
payload_on: "ON"
payload_off: "OFF"
optimistic: false
retain: true
I cut my blinds over to covers. I don’t know that there is anything different here, and I didn’t see anything that was necessarily wrong with your setup, but I can’t compare apples to apples since I have cut over to a cover instead of a light.
cover:
- platform: mqtt
name: "Window Bottom Center"
state_topic: "blind/bc/state"
command_topic: "blind/bc/command"
position_topic: "blind/bc/lstate"
set_position_topic: "blind/bc/level"
tilt_min: 0
tilt_max: 180
qos: 0
payload_open: "ON"
payload_close: "OFF"
retain: true
Nice one. Just tried this last night. Tasmota wasn’t doing the job for me so gave this a try and it worked great. Had a slight issue with the servo always wanting to go the wrong way for the first half a second so I commented out the delay(500)
lines and it’s perfect now. Seems like payload_open
is no longer a valid option in HA but changing it to payload_on
worked fine. Cheers for uploading this!
@jjhtpc could you publish any updates to your code now that you’ve cut over to cover from light? For example you have position_topic now which isn’t part of the code in your repo. Just trying to muddle through this and would appreciate any additional advice. Thanks!
Edit: Got it working as lights with this config. I’ve moved to an ESPHome-based setup since quite a bit has advanced on that front since this was first published - it makes things quite a bit less complicated. Will post my code when I have it cleaned up.
Hi @planetix , do you mind posting your ESPHome code? I’m trying to do the same thing but really not sure how or where to start.
I already have a tested and working version of a blind with ESPhome here if you’re interested.
It will only run one blind per ESP if you don’t have a problem with that.
Thank you, I will check it out.
Thanks to the tips in this thread, got my blinds automated with MQTT. Thanks!