Require a password to enable OTA mode
[doorlock_v1.git] / doorlock_v1.ino
1 #include <SPI.h>
2 #include <ESP8266WiFi.h>
3 #include <MFRC522.h>
4 #include <Adafruit_NeoPixel.h>
5 #include <FS.h>
6
7
8 #include "config.h"
9 #include "tag_handler.h"
10 #include "client.h"
11
12 MFRC522 mfrc522(SS_PIN, RST_PIN);
13
14 Adafruit_NeoPixel led = Adafruit_NeoPixel(9, LED_PIN, NEO_GRB + NEO_KHZ800);
15
16 // when did we last try to connect to wifi
17 unsigned long last_try = 0;
18
19 // is the wifi up and connected
20 bool wifi_connected() 
21 {
22   if (WiFi.status() == WL_CONNECTED) return true;
23   return false;
24 }
25
26 // try and connect us, but give up after a while
27 bool wifi_connect()
28 {
29   int count = 0;
30   int pulse = 0;
31   int rate = 32;
32
33   if (WiFi.status() == WL_CONNECTED) return true;
34
35
36   Serial.print(F("WiFi Connecting to "));
37   Serial.println(WIFI_SSID);
38   
39   WiFi.begin(WIFI_SSID, WIFI_PASS);
40   while (WiFi.status() != WL_CONNECTED && count < WIFI_COUNT) {
41     Serial.print(".");
42     led.setPixelColor(0, 0, 0, pulse);
43     led.show();
44     pulse += rate;
45     if (pulse <= 0 || pulse >= 192) rate=-rate;
46     delay(WIFI_DELAY);
47     count++;
48   }
49   if (WiFi.status() == WL_CONNECTED) {
50     Serial.print(F("Connected. IP="));
51     Serial.println(WiFi.localIP());
52     return true;
53   }
54   Serial.println(F("Wifi connect failed."));
55   return false;
56 }
57
58 // unrecoverable error state
59 // pulse red
60 void error_loop()
61 {
62   int pulse = 0;
63   int rate = 8;
64   while (1) {
65     led.setPixelColor(0, pulse, 0, 0);
66     led.show();
67     pulse += rate;
68     if (pulse <= 0 || pulse >= 256) rate=-rate;
69     delay(50);
70   }
71 }
72
73
74 // Lock is idle, colour indicates online or not
75 void led_status(bool has_wifi)
76 {
77   // must be neatly divisible to work
78   static int pulse = 32;
79   static int rate = -2;
80   
81   if (has_wifi) {
82     led.setPixelColor(0, pulse, pulse, pulse);
83   } else {
84     led.setPixelColor(0, pulse, pulse, 0);
85   }
86   led.show();
87
88   pulse += rate;
89   if (pulse == 0 || pulse == 32) rate=-rate;
90 }
91
92 void setup() {
93   SPI.begin();
94   
95   Serial.begin(9600);
96   Serial.println(F("\n\nRFID Doorlock. v1"));
97
98   pinMode(LOCK_PIN, OUTPUT);
99   digitalWrite(LOCK_PIN, LOW);
100
101   // Enable and clear LEDs
102   pinMode(LED_PIN, OUTPUT);
103   led.begin();
104   led.setBrightness(64);
105   led.show();
106
107   // Test comms with the RFID board
108   mfrc522.PCD_Init();
109   byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
110
111   if (v == 0) {
112     Serial.println(F("RFID Init failed"));
113     error_loop();
114   }
115   Serial.print(F("MFRC Rev 0x"));
116   Serial.println(v, HEX);
117
118   // connect and indicate
119   led_status( wifi_connect() );
120   last_try = millis();
121
122   // check if we have a keyfile
123   SPIFFS.begin();
124
125   if (SPIFFS.exists(KEYS_FILE)) {
126     Serial.print(F("Found keys file "));
127     Serial.println(KEYS_FILE);
128   } else {
129     Serial.print(F("Keys file "));
130     Serial.print(KEYS_FILE);
131     Serial.println(F(" not found"));
132   }
133
134
135   ESP.wdtEnable(5000);
136 }
137
138 void open_lock()
139 {
140   led.setPixelColor(0, 0, 255, 0);
141   led.show();
142   digitalWrite(LOCK_PIN, HIGH);
143   delay(3000);
144   digitalWrite(LOCK_PIN, LOW);
145   led.setPixelColor(0, 0, 0, 0);
146   led.show();
147 }
148
149 void fail_lock() 
150 {
151   led.setPixelColor(0, 255, 0, 0);
152   led.show();
153   delay(3000);
154   led.setPixelColor(0, 0, 0, 0);
155   led.show();
156   
157 }
158
159 void loop() {
160   MFRC522::Uid uid;
161   int count = 0;
162   bool success = false;
163
164   ESP.wdtFeed();
165   while (uid_fetch(mfrc522, uid, count)) {
166     Serial.print("Card: ");
167     Serial.print(uid_print(uid));
168     
169     if (uid_valid(uid)) {
170       Serial.println(" MATCH");
171       open_lock();
172       success = true;
173     } else {
174       Serial.println(" FAILED");
175       fail_lock();
176     }
177     
178     // wifi is up, report it
179     if (wifi_connected()) {
180       log_attempt(uid_print(uid), success);
181     }
182   }
183   
184   led_status( wifi_connected() );
185
186   // wifi isnt connected, time to try again ?
187   if (!wifi_connected()) {
188     unsigned int now = millis();
189     if ( last_try + WIFI_RETRY < now) {
190       Serial.print("now="); Serial.print(now);
191       Serial.print(" last="); Serial.print(last_try);
192       Serial.print(" then="); Serial.println(last_try + WIFI_RETRY);
193       led_status( wifi_connect() );
194       last_try = now;
195     }
196   }
197   
198   // dont spin too fast
199   delay(100);
200
201 }