Implement full support for two shutters
This commit is contained in:
33
include/main.h
Normal file
33
include/main.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <ArduinoHA.h>
|
||||
|
||||
void initPins();
|
||||
|
||||
void initWifi();
|
||||
|
||||
void initHA();
|
||||
|
||||
void onCoverLeftCommand(HACover::CoverCommand cmd);
|
||||
|
||||
void onCoverRightCommand(HACover::CoverCommand cmd);
|
||||
|
||||
void onCoverLeftSetPositionCommand(uint8_t pos);
|
||||
|
||||
void onCoverRightSetPositionCommand(uint8_t pos);
|
||||
|
||||
void processStateLeft();
|
||||
|
||||
void processStateRight();
|
||||
|
||||
void sendCoverLeftOpen();
|
||||
|
||||
void sendCoverLeftStop();
|
||||
|
||||
void sendCoverLeftClose();
|
||||
|
||||
void sendCoverRightOpen();
|
||||
|
||||
void sendCoverRightStop();
|
||||
|
||||
void sendCoverRightClose();
|
||||
|
||||
void sendRemoteCommand();
|
||||
333
src/main.cpp
Normal file
333
src/main.cpp
Normal file
@@ -0,0 +1,333 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ArduinoHA.h>
|
||||
#include <main.h>
|
||||
|
||||
#define BROKER_ADDR IPAddress(192,168,1,46)
|
||||
#define WIFI_SSID "Heimathafen"
|
||||
#define WIFI_PASSWORD "43762579905371198122"
|
||||
#define COVER_CLOSING_TIME_TOTAL_MILLIS 27500
|
||||
#define REMOTE_BUTTON_PRESS_LENGTH_MILLIS 1000
|
||||
#define REMOTE_BUTTON_PRESS_COOLDOWN_MILLIS 500
|
||||
#define MAX_REMOTE_COMMAND_QUEUE_LENGTH 20
|
||||
#define PIN_LEFT_OPEN D5
|
||||
#define PIN_LEFT_CLOSE D6
|
||||
#define PIN_RIGHT_OPEN D7
|
||||
#define PIN_RIGHT_CLOSE D8
|
||||
|
||||
byte mac[] = {0x00, 0x10, 0xFA, 0x6E, 0x38, 0x4A};
|
||||
|
||||
enum CoverState {
|
||||
Stopped,
|
||||
Opening,
|
||||
Closing
|
||||
};
|
||||
|
||||
enum RemoteCommands {
|
||||
None,
|
||||
LeftOpen,
|
||||
LeftClose,
|
||||
RightOpen,
|
||||
RightClose
|
||||
};
|
||||
|
||||
enum RemoteState {
|
||||
Idle,
|
||||
Busy,
|
||||
Cooldown
|
||||
};
|
||||
|
||||
int remoteCommandQueue[MAX_REMOTE_COMMAND_QUEUE_LENGTH] = { RemoteCommands::None };
|
||||
int remoteCommandQueueLength = 0;
|
||||
|
||||
WiFiClient client;
|
||||
HADevice device(mac, sizeof(mac));
|
||||
HAMqtt mqtt(client, device);
|
||||
HACover coverLeft("rolladen-wohnzimmer-links", false, false);
|
||||
HACover coverRight("rolladen-wohnzimmer-rechts", false, false);
|
||||
String lastCommandLeft = "";
|
||||
String lastCommandRight = "";
|
||||
int currentPositionLeft = 0;
|
||||
int currentPositionRight = 0;
|
||||
int targetPositionLeft = 0;
|
||||
int targetPositionRight = 0;
|
||||
unsigned long startMovingLeftMillis = 0;
|
||||
unsigned long startMovingRightMillis = 0;
|
||||
CoverState currentStateLeft = CoverState::Stopped;
|
||||
CoverState currentStateRight = CoverState::Stopped;
|
||||
unsigned long startSendRemoteCommandMillis = 0;
|
||||
int remoteState = RemoteState::Idle;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("Starting...");
|
||||
initPins();
|
||||
initWifi();
|
||||
initHA();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
mqtt.loop();
|
||||
processStateLeft();
|
||||
processStateRight();
|
||||
sendRemoteCommand();
|
||||
}
|
||||
|
||||
void initPins() {
|
||||
pinMode(PIN_LEFT_OPEN, OUTPUT);
|
||||
pinMode(PIN_LEFT_CLOSE, OUTPUT);
|
||||
pinMode(PIN_RIGHT_OPEN, OUTPUT);
|
||||
pinMode(PIN_RIGHT_CLOSE, OUTPUT);
|
||||
digitalWrite(PIN_LEFT_OPEN, LOW);
|
||||
digitalWrite(PIN_LEFT_CLOSE, LOW);
|
||||
digitalWrite(PIN_RIGHT_OPEN, LOW);
|
||||
digitalWrite(PIN_RIGHT_CLOSE, LOW);
|
||||
}
|
||||
|
||||
void initWifi() {
|
||||
// connect to wifi
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(500); // waiting for the connection
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println("Connected to the network");
|
||||
}
|
||||
|
||||
void initHA() {
|
||||
coverLeft.onCommand(onCoverLeftCommand);
|
||||
coverRight.onCommand(onCoverRightCommand);
|
||||
coverLeft.onSetPositionCommand(onCoverLeftSetPositionCommand);
|
||||
coverRight.onSetPositionCommand(onCoverRightSetPositionCommand);
|
||||
|
||||
// set device's details (optional)
|
||||
device.setName("NodeMCU_Rollladen_Wohnzimmer");
|
||||
device.setSoftwareVersion("1.0.0");
|
||||
|
||||
mqtt.begin(BROKER_ADDR);
|
||||
}
|
||||
|
||||
void onCoverLeftCommand(HACover::CoverCommand cmd) {
|
||||
if (cmd == HACover::CommandOpen) {
|
||||
Serial.println("Received Command: Open");
|
||||
if(targetPositionLeft != 100) {
|
||||
sendCoverLeftStop();
|
||||
targetPositionLeft = 100;
|
||||
}
|
||||
} else if (cmd == HACover::CommandClose) {
|
||||
Serial.println("Received Command: Close");
|
||||
if(targetPositionLeft != 0) {
|
||||
sendCoverLeftStop();
|
||||
targetPositionLeft = 0;
|
||||
}
|
||||
} else if (cmd == HACover::CommandStop) {
|
||||
Serial.println("Received Command: Stop");
|
||||
sendCoverLeftStop();
|
||||
}
|
||||
}
|
||||
|
||||
void onCoverRightCommand(HACover::CoverCommand cmd) {
|
||||
if (cmd == HACover::CommandOpen) {
|
||||
Serial.println("Received Command: Open");
|
||||
if(targetPositionRight != 100) {
|
||||
sendCoverRightStop();
|
||||
targetPositionRight = 100;
|
||||
}
|
||||
} else if (cmd == HACover::CommandClose) {
|
||||
Serial.println("Received Command: Close");
|
||||
if(targetPositionRight != 0) {
|
||||
sendCoverRightStop();
|
||||
targetPositionRight = 0;
|
||||
}
|
||||
} else if (cmd == HACover::CommandStop) {
|
||||
Serial.println("Received Command: Stop");
|
||||
sendCoverRightStop();
|
||||
}
|
||||
}
|
||||
|
||||
void onCoverLeftSetPositionCommand(uint8_t pos) {
|
||||
Serial.println("Received Set Position Command: " + String(pos));
|
||||
sendCoverLeftStop();
|
||||
targetPositionLeft = pos;
|
||||
}
|
||||
|
||||
void onCoverRightSetPositionCommand(uint8_t pos) {
|
||||
Serial.println("Received Set Position Command: " + String(pos));
|
||||
sendCoverRightStop();
|
||||
targetPositionRight = pos;
|
||||
}
|
||||
|
||||
void processStateLeft() {
|
||||
if(currentStateLeft == CoverState::Stopped) {
|
||||
if(targetPositionLeft < currentPositionLeft) {
|
||||
sendCoverLeftClose();
|
||||
}
|
||||
if(targetPositionLeft > currentPositionLeft) {
|
||||
sendCoverLeftOpen();
|
||||
}
|
||||
}
|
||||
if(currentStateLeft == CoverState::Closing || currentStateLeft == CoverState::Opening) {
|
||||
unsigned long targetMovementTime = abs(currentPositionLeft - targetPositionLeft) * COVER_CLOSING_TIME_TOTAL_MILLIS / 100;
|
||||
unsigned long currentMovementTime = millis() - startMovingLeftMillis;
|
||||
if(currentMovementTime > targetMovementTime) {
|
||||
sendCoverLeftStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processStateRight() {
|
||||
if(currentStateRight == CoverState::Stopped) {
|
||||
if(targetPositionRight < currentPositionRight) {
|
||||
sendCoverRightClose();
|
||||
}
|
||||
if(targetPositionRight > currentPositionRight) {
|
||||
sendCoverRightOpen();
|
||||
}
|
||||
}
|
||||
if(currentStateRight == CoverState::Closing || currentStateRight == CoverState::Opening) {
|
||||
unsigned long targetMovementTime = abs(currentPositionRight - targetPositionRight) * COVER_CLOSING_TIME_TOTAL_MILLIS / 100;
|
||||
unsigned long currentMovementTime = millis() - startMovingRightMillis;
|
||||
if(currentMovementTime > targetMovementTime) {
|
||||
sendCoverRightStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sendCoverLeftOpen() {
|
||||
coverLeft.setState(HACover::StateOpening);
|
||||
Serial.println("Send Cover Left: OPEN.");
|
||||
remoteCommandQueue[remoteCommandQueueLength] = RemoteCommands::LeftOpen;
|
||||
remoteCommandQueueLength++;
|
||||
currentStateLeft = CoverState::Opening;
|
||||
startMovingLeftMillis = millis();
|
||||
}
|
||||
|
||||
void sendCoverLeftStop() {
|
||||
int movementDiff = (millis() - startMovingLeftMillis) * 100 / COVER_CLOSING_TIME_TOTAL_MILLIS;
|
||||
if(currentStateLeft == CoverState::Opening) {
|
||||
Serial.println("Send Cover Left: CLOSE TO STOP.");
|
||||
remoteCommandQueue[remoteCommandQueueLength] = RemoteCommands::LeftClose;
|
||||
remoteCommandQueueLength++;
|
||||
currentPositionLeft = currentPositionLeft + movementDiff;
|
||||
}
|
||||
if(currentStateLeft == CoverState::Closing) {
|
||||
Serial.println("Send Cover Left: OPEN TO STOP.");
|
||||
remoteCommandQueue[remoteCommandQueueLength] = RemoteCommands::LeftOpen;
|
||||
remoteCommandQueueLength++;
|
||||
currentPositionLeft = currentPositionLeft - movementDiff;
|
||||
}
|
||||
|
||||
currentStateLeft = CoverState::Stopped;
|
||||
targetPositionLeft = currentPositionLeft;
|
||||
|
||||
coverLeft.setState(HACover::StateStopped);
|
||||
coverLeft.setPosition(currentPositionLeft);
|
||||
// Serial.println("Current Position: " + String(currentPositionLeft));
|
||||
}
|
||||
|
||||
void sendCoverLeftClose() {
|
||||
coverLeft.setState(HACover::StateClosing);
|
||||
Serial.println("Send Cover Left: CLOSE.");
|
||||
remoteCommandQueue[remoteCommandQueueLength] = RemoteCommands::LeftClose;
|
||||
remoteCommandQueueLength++;
|
||||
currentStateLeft = CoverState::Closing;
|
||||
startMovingLeftMillis = millis();
|
||||
}
|
||||
|
||||
void sendCoverRightOpen() {
|
||||
coverRight.setState(HACover::StateOpening);
|
||||
Serial.println("Send Cover Right: OPEN.");
|
||||
remoteCommandQueue[remoteCommandQueueLength] = RemoteCommands::RightOpen;
|
||||
remoteCommandQueueLength++;
|
||||
currentStateRight = CoverState::Opening;
|
||||
startMovingRightMillis = millis();
|
||||
}
|
||||
|
||||
void sendCoverRightStop() {
|
||||
int movementDiff = (millis() - startMovingRightMillis) * 100 / COVER_CLOSING_TIME_TOTAL_MILLIS;
|
||||
if(currentStateRight == CoverState::Opening) {
|
||||
Serial.println("Send Cover Right: CLOSE TO STOP.");
|
||||
remoteCommandQueue[remoteCommandQueueLength] = RemoteCommands::RightClose;
|
||||
remoteCommandQueueLength++;
|
||||
currentPositionRight = currentPositionRight + movementDiff;
|
||||
}
|
||||
if(currentStateRight == CoverState::Closing) {
|
||||
Serial.println("Send Cover Right: OPEN TO STOP.");
|
||||
remoteCommandQueue[remoteCommandQueueLength] = RemoteCommands::RightOpen;
|
||||
remoteCommandQueueLength++;
|
||||
currentPositionRight = currentPositionRight - movementDiff;
|
||||
}
|
||||
|
||||
currentStateRight = CoverState::Stopped;
|
||||
targetPositionRight = currentPositionRight;
|
||||
|
||||
coverRight.setState(HACover::StateStopped);
|
||||
coverRight.setPosition(currentPositionRight);
|
||||
// Serial.println("Current Position: " + String(currentPositionRight));
|
||||
}
|
||||
|
||||
void sendCoverRightClose() {
|
||||
coverRight.setState(HACover::StateClosing);
|
||||
Serial.println("Send Cover Right: CLOSE.");
|
||||
remoteCommandQueue[remoteCommandQueueLength] = RemoteCommands::RightClose;
|
||||
remoteCommandQueueLength++;
|
||||
currentStateRight = CoverState::Closing;
|
||||
startMovingRightMillis = millis();
|
||||
}
|
||||
|
||||
void sendRemoteCommand() {
|
||||
// Stop sending remote command
|
||||
if(remoteState == RemoteState::Busy && millis() - REMOTE_BUTTON_PRESS_LENGTH_MILLIS > startSendRemoteCommandMillis) {
|
||||
Serial.println("RemoteState::Cooldown");
|
||||
remoteState = RemoteState::Cooldown;
|
||||
digitalWrite(PIN_LEFT_OPEN, LOW);
|
||||
digitalWrite(PIN_LEFT_CLOSE, LOW);
|
||||
digitalWrite(PIN_RIGHT_OPEN, LOW);
|
||||
digitalWrite(PIN_RIGHT_CLOSE, LOW);
|
||||
}
|
||||
|
||||
// Wait Cooldown before sending next button press
|
||||
if(remoteState == RemoteState::Cooldown && millis() - REMOTE_BUTTON_PRESS_LENGTH_MILLIS - REMOTE_BUTTON_PRESS_COOLDOWN_MILLIS > startSendRemoteCommandMillis) {
|
||||
Serial.println("RemoteState::Idle");
|
||||
remoteState = RemoteState::Idle;
|
||||
}
|
||||
|
||||
// Send next command
|
||||
if (remoteState == RemoteState::Idle && remoteCommandQueueLength > 0) {
|
||||
// Serial.println("remoteCommandQueueLength: " + String(remoteCommandQueueLength));
|
||||
int nextCommand = remoteCommandQueue[0];
|
||||
remoteCommandQueueLength--;
|
||||
|
||||
// Move all commands in Queue;
|
||||
for(int i = 0; i < MAX_REMOTE_COMMAND_QUEUE_LENGTH - 1; i++) {
|
||||
remoteCommandQueue[i] = remoteCommandQueue[i+1];
|
||||
}
|
||||
|
||||
switch (nextCommand)
|
||||
{
|
||||
case RemoteCommands::LeftOpen:
|
||||
Serial.println("Remote: Press Button Left Open");
|
||||
digitalWrite(PIN_LEFT_OPEN, HIGH);
|
||||
break;
|
||||
case RemoteCommands::LeftClose:
|
||||
Serial.println("Remote: Press Button Left Close");
|
||||
digitalWrite(PIN_LEFT_CLOSE, HIGH);
|
||||
break;
|
||||
case RemoteCommands::RightOpen:
|
||||
Serial.println("Remote: Press Button Right Open");
|
||||
digitalWrite(PIN_RIGHT_OPEN, HIGH);
|
||||
break;
|
||||
case RemoteCommands::RightClose:
|
||||
Serial.println("Remote: Press Button Right Close");
|
||||
digitalWrite(PIN_RIGHT_CLOSE, HIGH);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println("RemoteState::Busy");
|
||||
remoteState = RemoteState::Busy;
|
||||
startSendRemoteCommandMillis = millis();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user