EmlaLockSafe
UnlockSafeView.h
Go to the documentation of this file.
1
5#pragma once
6
7#include "../LockState.h"
8#include "../Tools.h"
9#include "../configuration/Configuration.h"
10#include "ViewStore.h"
11
12#include <DialogOK.h>
13#include <MenuView.h>
14#include <RotaryEncoder.h>
15#include <ViewBase.h>
16#include <time.h>
17
18namespace views {
22class UnlockSafeView : public lcd::ViewBase {
23protected:
27 RotaryEncoder* encoder;
28
29protected:
33 const int numberOfColumns;
34
35protected:
39 const int numberOfRows;
40
41protected:
46
47public:
56 UnlockSafeView(LiquidCrystal_PCF8574* display, RotaryEncoder* encoder, const int& numberOfColumns, const int& numberOfRows)
57 : lcd::ViewBase(display, "UnlockSafeView")
61
62public:
66 UnlockSafeView(const UnlockSafeView& other) = delete;
67
68public:
72 UnlockSafeView(UnlockSafeView&& other) noexcept = delete;
73
74protected:
78 virtual void activate() {
79 display->clear();
80 display->setCursor(0, 0);
81 display->print("Verifying Emlalock");
82
83 activationTime = time(NULL);
84 // only update trigger the api if the last update time is not in the future.
85 // The time will be in the future if an emergency key was entered.
86 if (LockState::getLastUpdateTime() < time(NULL)) {
88 }
89
90 // since tick is blocking we should never call it directly from here...
91 }
92
93public:
99 virtual void tick(const bool& forceRedraw) {
100 // Show the wait animation
101 Tools::waitAnimation(display, [this]() -> bool {
102 return (LockState::getLastUpdateTime() < activationTime) && (time(NULL) - activationTime < 15);
103 });
104
105 // Did we run in a 15s timeout?
107 digitalWrite(COIL_PIN, SAFE_COIL_LOCKED);
108 lcd::DialogOk(display, encoder, "The Emlalock API\ndid not answer\nwithin 15s.", numberOfColumns, numberOfRows).showModal();
109 activatePreviousView();
110 return;
111 }
112
113 // Should the safe be locked
115 if ((LockState::getEndDate() > time(NULL)) &&
117 (config.getAutoLockHygieneOpeningTimeout() && (LockState::getCleaningEndDate() < time(NULL))))) {
118 digitalWrite(COIL_PIN, SAFE_COIL_LOCKED);
119 activatePreviousView();
120 return;
121 }
122
123 // Activate the coil if necessary
124 static unsigned long coilActivationTime = 0;
125 if (!digitalRead(COIL_PIN)) {
126 display->clear();
127 display->setCursor(0, 0);
128 display->print("Safe unlocked");
129 coilActivationTime = millis();
130 digitalWrite(COIL_PIN, SAFE_COIL_UNLOCKED);
131 }
132
133 // show a animation showing how many time is lest until the coil is released
134 // again
135 display->setCursor(0, 1);
136 for (int i = 0; i < (millis() - coilActivationTime) / 500; i++) {
137 display->write('=');
138 }
139
140 // Check if the coil should be released after 10 seconds
141 if ((millis() - coilActivationTime > 10000) || (encoder->getNewClick())) {
142 digitalWrite(COIL_PIN, SAFE_COIL_LOCKED);
143 activatePreviousView();
144 }
145 }
146};
147} // namespace views
#define COIL_PIN
GPIO the coil of the safe is connected to.
Definition: HardwareConfiguration.h:10
#define SAFE_COIL_UNLOCKED
Value of the COIL_PIN if the coil should be unlocked.
Definition: HardwareConfiguration.h:30
#define SAFE_COIL_LOCKED
Value of the COIL_PIN if the coil should be locked.
Definition: HardwareConfiguration.h:25
static const time_t & getEndDate()
Get the End Date.
Definition: LockState.h:325
static const time_t & getLastUpdateTime()
Get the time of the last update over the emlalock api.
Definition: LockState.h:438
static const time_t & getCleaningEndDate()
Get the End Date of the current cleaning opening (or 0)
Definition: LockState.h:416
static void waitAnimation(LiquidCrystal_PCF8574 *display, std::function< bool()> stillActive)
Shows the animation while waiting until the callback returns false.
Definition: Tools.h:69
Static class accessing the configuration.
Definition: Configuration.h:20
const bool & getAutoLockHygieneOpeningTimeout() const
return if the safe should automatically lock after the time for hygiene opening is over....
Definition: Configuration.h:346
static Configuration & getSingleton()
Get the Singleton object.
Definition: Configuration.h:162
void triggerRefresh()
Triggers the client to reload the current state from the EmlaLock server.
Definition: EmlaLockApi.h:105
static EmlaLockApi & getSingleton(bool offlineMode=false)
Get the singleton instance of the API handler.
Definition: EmlaLockApi.h:71
View used to unlock the safe.
Definition: UnlockSafeView.h:22
UnlockSafeView(const UnlockSafeView &other)=delete
Copy constructor - not available.
virtual void tick(const bool &forceRedraw)
called during the loop function
Definition: UnlockSafeView.h:99
virtual void activate()
called as soon as the view becomes active
Definition: UnlockSafeView.h:78
const int numberOfRows
Number of display-rows.
Definition: UnlockSafeView.h:39
RotaryEncoder * encoder
pointer to the encoder instance
Definition: UnlockSafeView.h:27
const int numberOfColumns
Number of display-columns.
Definition: UnlockSafeView.h:33
UnlockSafeView(UnlockSafeView &&other) noexcept=delete
Move constructor - not available.
UnlockSafeView(LiquidCrystal_PCF8574 *display, RotaryEncoder *encoder, const int &numberOfColumns, const int &numberOfRows)
Construct the vie.
Definition: UnlockSafeView.h:56
time_t activationTime
Time when this view was activated.
Definition: UnlockSafeView.h:45
views::ConfigurationServerView configurationServerView & display
Definition: main.cpp:57
Definition: ConfigurationServerView.h:10