200 lines
3.5 KiB
C++
200 lines
3.5 KiB
C++
#undef ARDUINO_M5STACK_FIRE
|
|
#define ARDUINO_M5STACK_Paper
|
|
|
|
#define YAML_DISABLE_CJSON
|
|
|
|
#define LGFX_M5PAPER
|
|
#define LGFX_USE_V1
|
|
#define LGFX_AUTODETECT
|
|
|
|
#include <M5EPD.h>
|
|
#include <WiFi.h>
|
|
#include <NTPClient.h>
|
|
#include <HTTPClient.h>
|
|
|
|
#include "display.hpp"
|
|
#include "keypad.hpp"
|
|
#include "input.hpp"
|
|
#include "status.hpp"
|
|
#include "lock.hpp"
|
|
#include "touch.hpp"
|
|
#include "settings.hpp"
|
|
#include "mqtt.hpp"
|
|
|
|
static MQTT *mqtt;
|
|
|
|
static Display display;
|
|
static Keypad *keypad;
|
|
static Status *status;
|
|
static Input *input;
|
|
static Touch *touch;
|
|
static Lock *keylock;
|
|
|
|
void keypad_state(bool enabled)
|
|
{
|
|
for (int i = 0; i < 11; i++)
|
|
{
|
|
keypad->set_enabled(i, enabled);
|
|
}
|
|
keypad->set_enabled(11, !enabled);
|
|
}
|
|
|
|
static bool is_disarmed = false;
|
|
|
|
static const int WIFI_CONNECT_RETRY_MAX = 30;
|
|
|
|
void mqtt_callback(char *topic, byte *payload, unsigned int length)
|
|
{
|
|
payload[length] = '\0';
|
|
String state((const char *)payload);
|
|
is_disarmed = state == "disarmed";
|
|
|
|
state.replace("_", " ");
|
|
state[0] = toupper(state[0]);
|
|
Serial.println(state);
|
|
status->set(state);
|
|
status->draw(&display);
|
|
|
|
keypad_state(!is_disarmed);
|
|
}
|
|
|
|
void lock()
|
|
{
|
|
if (is_disarmed)
|
|
{
|
|
mqtt->send("ARM_AWAY");
|
|
}
|
|
}
|
|
|
|
void unlock()
|
|
{
|
|
mqtt->send("DISARM");
|
|
}
|
|
|
|
void submit(String code)
|
|
{
|
|
if (!keylock->check(code))
|
|
{
|
|
status->set("Invalid");
|
|
return;
|
|
}
|
|
|
|
unlock();
|
|
}
|
|
|
|
bool isConnecting = false;
|
|
void initWifi(Settings *settings)
|
|
{
|
|
if (!settings)
|
|
{
|
|
status->set("No settings");
|
|
return;
|
|
}
|
|
|
|
if (isConnecting)
|
|
{
|
|
status->set("Already connecting");
|
|
return;
|
|
}
|
|
|
|
isConnecting = true;
|
|
status->set("Connecting");
|
|
|
|
WiFi.begin(settings->gettext("wifi:ssid"), settings->gettext("wifi:password"));
|
|
|
|
if (WiFi.isConnected())
|
|
{
|
|
WiFi.disconnect();
|
|
}
|
|
|
|
Serial.print("Connecting to Wi-Fi network");
|
|
for (int cnt_retry = 0; cnt_retry < WIFI_CONNECT_RETRY_MAX && !WiFi.isConnected();
|
|
cnt_retry++)
|
|
{
|
|
delay(500);
|
|
Serial.print(".");
|
|
}
|
|
Serial.println("");
|
|
if (WiFi.isConnected())
|
|
{
|
|
Serial.print("Local IP: ");
|
|
Serial.println(WiFi.localIP());
|
|
isConnecting = false;
|
|
status->set("Connected");
|
|
}
|
|
else
|
|
{
|
|
status->set("Failed to connect");
|
|
isConnecting = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
void p(int v)
|
|
{
|
|
switch (v)
|
|
{
|
|
case 9:
|
|
input->clear();
|
|
break;
|
|
case 10:
|
|
input->append("0");
|
|
break;
|
|
case 11:
|
|
lock();
|
|
break;
|
|
default:
|
|
input->append(v + 1);
|
|
break;
|
|
}
|
|
|
|
if (input->length() >= 6)
|
|
{
|
|
// verify
|
|
input->draw(&display); // force one more redraw for the last character
|
|
submit(input->get_value());
|
|
input->clear();
|
|
}
|
|
}
|
|
|
|
void setup()
|
|
{
|
|
M5.begin();
|
|
display.init();
|
|
touch = new Touch(M5.TP);
|
|
status = new Status("Loading");
|
|
keypad = new Keypad(&display);
|
|
keypad->addListener("pressed", p);
|
|
input = new Input("", keypad->get_width(), 0, display.width() - keypad->get_width(), 115);
|
|
|
|
auto settings = new Settings();
|
|
|
|
if (!settings)
|
|
{
|
|
status->set("Settings Error");
|
|
return;
|
|
}
|
|
|
|
initWifi(settings);
|
|
|
|
keylock = new Lock(settings);
|
|
|
|
mqtt = new MQTT(settings, mqtt_callback);
|
|
mqtt->connect();
|
|
|
|
keylock->begin();
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
mqtt->loop();
|
|
|
|
auto tap = touch->tap();
|
|
if (tap.has_value())
|
|
keypad->update(tap.value());
|
|
|
|
keypad->draw();
|
|
input->draw(&display);
|
|
status->draw(&display);
|
|
}
|