Implement full support for two shutters

This commit is contained in:
2022-02-20 20:47:24 +01:00
parent e294ee9cf3
commit c872facfa8
2 changed files with 366 additions and 0 deletions

33
include/main.h Normal file
View 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
View 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();
}
}