Subversion Repositories ESP8266_P1_Meter

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 raymond 1
#include <Arduino.h>
2
#include <FS.h>
3
#include <LittleFS.h>
4
#include <ArduinoJson.h>
5
#include <AsyncFsWebServer.h>  // https://github.com/cotestatnt/async-esp-fs-webserver
6
#include <MFRC522v2.h>         // https://github.com/OSSLibraries/Arduino_MFRC522v2
7
#include <MFRC522DriverSPI.h>
8
#include <MFRC522DriverPinSimple.h>
9
#include <MFRC522Debug.h>
10
#include <time.h>
11
 
12
#define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"  // Timezone definition to get properly time from NTP server
13
 
14
/*
15
* To customize the appearance of the web pages, upload the login and rfid files 
16
* (without extensions) to the microcontroller's flash memory using built-in functionality (/setup webpage). 
17
* Set the following #define to false for send your pages instead of those embedded in the firmware. 
18
* You can find both files in the "/data" folder.
19
*/
20
#define USE_EMBEDDED_HTM true
21
 
22
#if USE_EMBEDDED_HTM
23
#include "data/html_login.h"
24
#include "data/html_rfid.h"
25
#endif
26
 
27
#define PIN_MISO    15
28
#define PIN_MOSI    16
29
#define PIN_SCLK    17
30
#define PIN_CS      18
31
 
32
uint32_t chipId = 0;                   // Unique ID of the ESP chip
33
bool addLogRecord = true;              // Flag to enable/disable log recording
34
 
35
MFRC522DriverPinSimple ss_pin(PIN_CS); // Configurable, see typical pin layout above.
36
MFRC522DriverSPI driver{ss_pin};       // Create SPI driver.
37
MFRC522 mfrc522{driver};               // Create MFRC522 instance.
38
struct tm ntp;                         // Time structure holding current time from NTP
39
 
40
#include "JsonDB.hpp"
41
#include "webserver.hpp"
42
 
43
TableManager usersTable("/users.json");
44
 
45
struct User_t{
46
  const char* username;
47
  const char* password;
48
  const char* name;
49
  const char* email;
50
  const char* tag;
51
  uint8_t level;
52
} ;
53
 
54
// Some test users
55
User_t users[] = {
56
  {"admin", "admin", "DB adminitrator", "", "", 5},
57
  {"user1", "", "John Doe", "jhon.doe@email.com", "12345", 1},
58
  {"user2", "", "Mark twain", "mark65@email.com", "67890", 1}
59
};
60
 
61
const char* uniqueKeys[] = {"tag", "username"};
62
 
63
//////////////////////////// Append a row to csv file ///////////////////////////////////
64
bool appendRow(const char* username, uint64_t tag) {
65
  getLocalTime(&ntp, 10);
66
 
67
  char filename[32];
68
  snprintf(filename, sizeof(filename),"/logs/%04d_%02d_%02d.csv", ntp.tm_year + 1900, ntp.tm_mon + 1, ntp.tm_mday);  
69
 
70
  File file = LittleFS.open("/logs");
71
  if (!file) {    
72
    LittleFS.mkdir("/logs");
73
    Serial.println("Created /logs directory");
74
  }
75
 
76
  if (LittleFS.exists(filename)) {
77
    file = LittleFS.open(filename, "a");   // Append to existing file
78
  }
79
  else {
80
    file = LittleFS.open(filename, "w");   // Create a new file    
81
    file.println("reader, username, tag, timestamp");
82
    Serial.printf("Created file %s\n", filename);
83
  }
84
 
85
  if (file) {
86
    char timestamp[25];
87
    strftime(timestamp, sizeof(timestamp), "%c", &ntp);
88
    char row[64];
89
    snprintf(row, sizeof(row), "%d, %s, %llu, %s", chipId, username, tag, timestamp);        
90
    Serial.println(row);
91
    file.println(row);
92
    file.close();
93
    return true;
94
  }
95
  return false;
96
}
97
 
98
void setup() {
99
  SPI.begin(PIN_SCLK, PIN_MISO, PIN_MOSI, PIN_CS);
100
  Serial.begin(115200);
101
  Serial.println("\n\n\n\nStarting ESP32 RFID gateway...");
102
 
103
  mfrc522.PCD_Init();                                       // Init MFRC522 board.
104
  MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial);	  // Show details of PCD - MFRC522 Card Reader details.
105
  Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
106
 
107
  if (!LittleFS.begin()) {         
108
    Serial.println("ERROR on mounting filesystem. It will be reformatted!");
109
    LittleFS.format();
110
    ESP.restart();
111
  }
112
 
113
  // LittleFS.remove("/users.json");
114
 
115
  // Load the users table
116
  usersTable.loadTable();
117
 
118
  for (User_t user: users){
119
    JsonDocument userDoc;
120
    userDoc["username"] = user.username;
121
    userDoc["password"] = getSHA256(user.password);
122
    userDoc["name"] = user.name;
123
    userDoc["email"] = user.email;
124
    userDoc["tag"] = user.tag;
125
    userDoc["level"] = user.level;
126
 
127
    if (usersTable.addRecord(userDoc.as<JsonObject>(), uniqueKeys, 2)) 
128
      Serial.println("Record added to table");
129
    else
130
      Serial.println("Error or record alreay present.");
131
  }
132
 
133
  // Start webserver
134
  startWebServer();
135
  // Set NTP servers
136
  #ifdef ESP8266
137
  configTime(MYTZ, "time.google.com", "time.windows.com", "pool.ntp.org");
138
  #elif defined(ESP32)
139
  configTzTime(MYTZ, "time.google.com", "time.windows.com", "pool.ntp.org");
140
  #endif
141
  // Wait for NTP sync (with timeout)
142
  getLocalTime(&ntp, 5000);
143
 
144
  #if defined(ESP32)
145
  for(byte i=0; i<17; i=i+8) {
146
    chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
147
  }
148
  #elif defined(ESP8266)
149
  chipId = ESP.getChipId();
150
  #endif
151
  Serial.print("ESP Chip ID: ");
152
  Serial.println(chipId);
153
}
154
 
155
void loop() {
156
  delay(10);
157
 
158
	if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
159
    static uint32_t readTime = millis();
160
    static uint64_t oldCode = 0;
161
 
162
    // The UID of an RFID tag can be up to 64bit long
163
    uint64_t tagCode = 0;   
164
 
165
    // tagCode is swapped, but it doesn't matter We need only it's a unique number
166
    for(byte i = 0; i < mfrc522.uid.size; i++) {
167
      tagCode |= mfrc522.uid.uidByte[i] << (8*i);
168
    }
169
 
170
    if ((tagCode != oldCode) || (millis() - readTime > 5000)) {
171
      readTime = millis();
172
      oldCode = tagCode;
173
 
174
      // Serial.printf("\nTag code: %llu\n", tagCode);
175
      if (addLogRecord) {                
176
        JsonObject user = usersTable.findRecord("tag", String(tagCode).c_str());
177
        if (user) {        
178
          const char* username = user["username"].as<const char*>();
179
          appendRow(username, tagCode);
180
        }
181
        else {
182
          appendRow("not allowed", tagCode);
183
        }
184
      }
185
    }
186
	}
187
}
188
 
189