Enclosure files + firmware

This commit is contained in:
Salim Benbouziyane
2024-12-27 16:11:21 -05:00
parent a0ae88370c
commit 5fd10e2f6b
62 changed files with 3587 additions and 1 deletions

View File

@@ -0,0 +1,57 @@
#include "StateMachine.h"
#include "Controllers.h"
void AdjustState::enter()
{
Serial.println("Entering Adjust State");
lastActivity = millis();
ledController.setSolid(AMBER);
// Register state-specific handlers
inputController.onPressHandler([this]()
{
Serial.println("Adjust State: Button pressed");
StateMachine::idleState.setTimer(this->adjustDuration);
displayController.showConfirmation();
stateMachine.changeState(&StateMachine::idleState); });
inputController.onEncoderRotateHandler([this](int delta)
{
Serial.println("Adjust State: Encoder turned");
Serial.println(delta);
// Update duration with delta and enforce bounds
this->adjustDuration += (delta * 5);
if (this->adjustDuration < MIN_TIMER) {
this->adjustDuration = MIN_TIMER;
} else if (this->adjustDuration > MAX_TIMER) {
this->adjustDuration = MAX_TIMER;
}
this->lastActivity = millis(); });
}
void AdjustState::update()
{
inputController.update();
displayController.drawAdjustScreen(adjustDuration);
if (millis() - lastActivity >= (CHANGE_TIMEOUT * 1000))
{
// Transition to Idle
stateMachine.changeState(&StateMachine::idleState);
}
}
void AdjustState::exit()
{
Serial.println("Exiting Adjust State");
inputController.releaseHandlers();
}
void AdjustState::adjustTimer(int duration)
{
adjustDuration = duration;
}

View File

@@ -0,0 +1,41 @@
#include "StateMachine.h"
#include "Controllers.h"
DoneState::DoneState() : doneEnter(0) {}
void DoneState::enter()
{
Serial.println("Entering Done State");
doneEnter = millis();
ledController.setBreath(GREEN, -1, true, 2);
// Register state-specific handlers
inputController.onPressHandler([]()
{
Serial.println("Done State: Button pressed");
stateMachine.changeState(&StateMachine::idleState); });
// Send 'Stop' webhook
networkController.sendWebhookAction("stop");
}
void DoneState::update()
{
inputController.update();
ledController.update();
displayController.drawDoneScreen();
if (millis() - doneEnter >= (CHANGE_TIMEOUT * 1000))
{
// Transition to Idle after timeout
stateMachine.changeState(&StateMachine::idleState);
}
}
void DoneState::exit()
{
Serial.println("Exiting Done State");
inputController.releaseHandlers();
}

View File

@@ -0,0 +1,87 @@
#include "StateMachine.h"
#include "Controllers.h"
IdleState::IdleState() : defaultDuration(0), lastActivity(0)
{
if (nvs_flash_init() != ESP_OK)
{
Serial.println("NVS Flash Init Failed");
}
else
{
Serial.println("NVS initialized successfully.");
}
// Load the default duration
if (preferences.begin("focusdial", true))
{
defaultDuration = preferences.getInt("timer", DEFAULT_TIMER);
preferences.end();
}
}
void IdleState::enter()
{
Serial.println("Entering Idle State");
ledController.setBreath(BLUE, -1, false, 5);
// Register state-specific handlers
inputController.onPressHandler([this]()
{
Serial.println("Idle State: Button pressed");
StateMachine::timerState.setTimer(this->defaultDuration, 0);
displayController.showTimerStart();
stateMachine.changeState(&StateMachine::timerState); // Start timer
});
inputController.onLongPressHandler([this]()
{
Serial.println("Idle State: Button long pressed");
stateMachine.changeState(&StateMachine::resetState); // Transition to Reset State
});
inputController.onEncoderRotateHandler([this](int delta)
{
Serial.println("Idle State: Encoder turned");
StateMachine::adjustState.adjustTimer(this->defaultDuration);
stateMachine.changeState(&StateMachine::adjustState); // Transition to Adjust State
});
lastActivity = millis(); // Activity timer
}
void IdleState::update()
{
static unsigned long lastUpdateTime = 0;
// Controllers updates
inputController.update();
ledController.update();
networkController.update();
displayController.drawIdleScreen(defaultDuration, networkController.isWiFiConnected());
// Check if sleep timeout is reached
if (millis() - lastActivity >= (SLEEP_TIMOUT * 60 * 1000))
{
Serial.println("Idle State: Activity timeout");
stateMachine.changeState(&StateMachine::sleepState); // Transition to Sleep State
}
}
void IdleState::exit()
{
Serial.println("Exiting Idle State");
inputController.releaseHandlers();
ledController.turnOff();
}
void IdleState::setTimer(int duration)
{
defaultDuration = duration;
preferences.begin("focusdial", true);
preferences.putInt("timer", defaultDuration);
preferences.end();
}

View File

@@ -0,0 +1,71 @@
#include "StateMachine.h"
#include "Controllers.h"
PausedState::PausedState() : duration(0), elapsedTime(0), pauseEnter(0) {}
void PausedState::enter()
{
Serial.println("Entering Paused State");
pauseEnter = millis(); // Record the time when the pause started
ledController.setBreath(YELLOW, -1, false, 20);
// Register state-specific handlers
inputController.onPressHandler([this]()
{
Serial.println("Paused State: Button Pressed");
// Send 'Start' webhook (resume)
networkController.sendWebhookAction("start");
// Transition back to TimerState with the stored duration and elapsed time
StateMachine::timerState.setTimer(duration, elapsedTime);
displayController.showTimerResume();
stateMachine.changeState(&StateMachine::timerState); // Transition back to Timer State
});
inputController.onDoublePressHandler([]()
{
Serial.println("Paused State: Button Double Pressed");
// Send 'Stop' webhook (canceled)
networkController.sendWebhookAction("stop");
displayController.showCancel();
stateMachine.changeState(&StateMachine::idleState); // Transition back to Idle State
});
}
void PausedState::update()
{
inputController.update();
ledController.update();
// Redraw the paused screen with remaining time
int remainingTime = (duration * 60) - elapsedTime;
displayController.drawPausedScreen(remainingTime);
unsigned long currentTime = millis();
// Check if the pause timeout has been reached
if (currentTime - pauseEnter >= (PAUSE_TIMEOUT * 60 * 1000))
{
// Timeout reached, transition to Idle State
Serial.println("Paused State: Timout");
// Send 'Stop' webhook (timeout)
networkController.sendWebhookAction("stop");
displayController.showCancel();
stateMachine.changeState(&StateMachine::idleState); // Transition back to Idle State
}
}
void PausedState::exit()
{
Serial.println("Exiting Paused State");
inputController.releaseHandlers();
}
void PausedState::setPause(int duration, unsigned long elapsedTime)
{
this->duration = duration;
this->elapsedTime = elapsedTime;
}

View File

@@ -0,0 +1,29 @@
#include "StateMachine.h"
#include "Controllers.h"
void ProvisionState::enter()
{
Serial.println("Entering Provision State");
inputController.releaseHandlers();
displayController.drawProvisionScreen();
ledController.setSolid(AMBER);
networkController.startProvisioning();
}
void ProvisionState::update()
{
ledController.update();
if (networkController.isWiFiProvisioned() && networkController.isWiFiConnected())
{
Serial.println("Provisioning Complete, WiFi Connected");
displayController.showConnected();
networkController.stopProvisioning();
stateMachine.changeState(&StateMachine::idleState);
}
}
void ProvisionState::exit()
{
Serial.println("Exiting Provision State");
networkController.stopProvisioning();
}

View File

@@ -0,0 +1,54 @@
#include "StateMachine.h"
#include "Controllers.h"
bool resetSelected = false; // button selection
void ResetState::enter()
{
Serial.println("Entering Reset State");
ledController.setBreath(MAGENTA, -1, false, 10);
// Register state-specific handlers
inputController.onEncoderRotateHandler([this](int delta)
{
if (delta > 0) {
resetSelected = true; // Select "RESET"
} else if (delta < 0) {
resetSelected = false; // Select "CANCEL"
} });
inputController.onPressHandler([this]()
{
if (resetSelected) {
Serial.println("Reset State: RESET button pressed, rebooting.");
displayController.showReset();
networkController.reset();
resetStartTime = millis();
} else {
Serial.println("Reset State: CANCEL button pressed, returning to Idle.");
displayController.showCancel();
stateMachine.changeState(&StateMachine::idleState);
} });
}
void ResetState::update()
{
inputController.update();
ledController.update();
displayController.drawResetScreen(resetSelected);
if (resetStartTime > 0 && (millis() - resetStartTime >= 1000))
{
Serial.println("Restarting ...");
ESP.restart(); // Restart after 1 second
}
}
void ResetState::exit()
{
Serial.println("Exiting Reset State");
inputController.releaseHandlers();
ledController.turnOff();
}

View File

@@ -0,0 +1,37 @@
#include "StateMachine.h"
#include "Controllers.h"
void SleepState::enter()
{
Serial.println("Entering Sleep State");
ledController.turnOff();
displayController.clear();
// Register state-specific handlers
inputController.onPressHandler([]()
{
Serial.println("Sleep State: Button pressed");
stateMachine.changeState(&StateMachine::idleState); });
inputController.onLongPressHandler([]()
{
Serial.println("Sleep State: long pressed");
stateMachine.changeState(&StateMachine::idleState); });
inputController.onEncoderRotateHandler([this](int delta)
{
Serial.println("Sleep State: Encoder turned");
stateMachine.changeState(&StateMachine::idleState); });
}
void SleepState::update()
{
inputController.update();
}
void SleepState::exit()
{
Serial.println("Exiting Sleep State");
inputController.releaseHandlers();
}

View File

@@ -0,0 +1,37 @@
#include "StateMachine.h"
#include "Controllers.h"
StartupState::StartupState() : startEnter(0) {}
void StartupState::enter()
{
Serial.println("Entering Splash State");
displayController.drawSplashScreen();
ledController.setSpinner(TEAL, -1);
startEnter = millis();
}
void StartupState::update()
{
ledController.update();
if (millis() - startEnter >= (SPLASH_DURATION * 1000))
{
if (networkController.isWiFiProvisioned())
{
stateMachine.changeState(&StateMachine::idleState); // Transition to Idle
}
else
{
stateMachine.changeState(&StateMachine::provisionState); // Trigger Provision
}
}
}
void StartupState::exit()
{
ledController.turnOff();
Serial.println("Exiting Splash State");
}

View File

@@ -0,0 +1,77 @@
#include "StateMachine.h"
#include "Controllers.h"
TimerState::TimerState() : duration(0), elapsedTime(0), startTime(0) {}
void TimerState::enter()
{
Serial.println("Entering Timer State");
// Start time based on the elapsed time
startTime = millis() - (elapsedTime * 1000);
displayController.drawTimerScreen(duration * 60);
ledController.startFillAndDecay(RED, ((duration * 60) - elapsedTime) * 1000);
// Register state-specific handlers
inputController.onPressHandler([this]()
{
Serial.println("Timer State: Button Pressed");
// Send 'Stop' webhook (pause)
networkController.sendWebhookAction("stop");
displayController.showTimerPause();
// Transition to PausedState and set elapsed time
StateMachine::pausedState.setPause(this->duration, this->elapsedTime); // Save current elapsed time
stateMachine.changeState(&StateMachine::pausedState); // Transition to Paused State
});
inputController.onDoublePressHandler([this]()
{
Serial.println("Timer State: Button Double Pressed");
// Send 'Stop' webhook (canceled)
networkController.sendWebhookAction("stop");
displayController.showCancel();
stateMachine.changeState(&StateMachine::idleState); // Transition to IdleState
});
networkController.startBluetooth();
networkController.sendWebhookAction("start");
}
void TimerState::update()
{
inputController.update();
ledController.update();
unsigned long currentTime = millis();
elapsedTime = (currentTime - startTime) / 1000;
int remainingSeconds = duration * 60 - elapsedTime;
displayController.drawTimerScreen(remainingSeconds);
// Check if the timer is done
if (remainingSeconds <= 0)
{
Serial.println("Timer State: Done");
displayController.showTimerDone();
stateMachine.changeState(&StateMachine::doneState); // Transition to Done State
}
}
void TimerState::exit()
{
inputController.releaseHandlers();
networkController.stopBluetooth();
ledController.turnOff();
Serial.println("Exiting Timer State");
}
void TimerState::setTimer(int duration, unsigned long elapsedTime)
{
this->duration = duration;
this->elapsedTime = elapsedTime;
}