29 |
30 |
106 |
107 |
108 |
112 |
113 |
114 |
115 | Connection with esp-rfid absent. Reconnecting...
116 |
117 |
118 |
119 |
120 |
138 |
139 |
140 |
141 |
142 |
146 |
147 |
Warning! Unexpected bad things will happen if you don’t read this!
148 |
149 |
150 |
151 | This action cannot be undone. This will permanently delete all the user data, settings and logs. Please make sure you made a backup first.
152 |
153 |
154 |
155 |
156 |
Please type in the hostname of the device to confirm.
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
167 |
168 |
169 |
170 |
198 |
199 |
200 |
201 |
202 |
206 |
207 | Warning! Please make sure you made a backup first
208 |
209 |
210 |
211 |
Latest Version Online
212 |
213 |
214 |
215 |
216 |
217 |
218 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
Current Version:
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
244 |
245 |
246 |
247 |
248 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
--------------------------------------------------------------------------------
/src/wifi.esp:
--------------------------------------------------------------------------------
1 | void setEnableWifi()
2 | {
3 | doEnableWifi = true;
4 | }
5 |
6 | void onWifiConnect(const WiFiEventStationModeConnected &event)
7 | {
8 | #ifdef DEBUG
9 | Serial.println(F("[ INFO ] WiFi STA Connected"));
10 | #endif
11 | mqttReconnectTimer.detach();
12 | if (!wifiReconnectTimer.active() && !config.fallbackMode)
13 | {
14 | wifiReconnectTimer.once(300, setEnableWifi);
15 | }
16 | ledWifiOff();
17 | }
18 |
19 | void onWifiDisconnect(const WiFiEventStationModeDisconnected &event)
20 | {
21 | if ( !WiFi.isConnected() )
22 | {
23 | return;
24 | }
25 | #ifdef DEBUG
26 | Serial.println(F("[ INFO ] WiFi STA Disconnected"));
27 | #endif
28 | mqttReconnectTimer.detach();
29 | disconnectMqtt();
30 | if (!wifiReconnectTimer.active() && !config.fallbackMode)
31 | {
32 | wifiReconnectTimer.once(300, setEnableWifi);
33 | }
34 | ledWifiOff();
35 | }
36 |
37 | void onWifiGotIP(const WiFiEventStationModeGotIP &event)
38 | {
39 | #ifdef DEBUG
40 | Serial.print("[ INFO ] WiFi IP Connected: ");
41 | Serial.println(WiFi.localIP().toString());
42 | #endif
43 | wifiReconnectTimer.detach();
44 | ledWifiOn();
45 | connectToMqtt();
46 | }
47 |
48 | bool ICACHE_FLASH_ATTR startAP(IPAddress apip, IPAddress apsubnet, bool hidden, const char *ssid, const char *password = NULL)
49 | {
50 | #ifdef DEBUG
51 | Serial.println(F("[ INFO ] ESP-RFID is running in AP Mode "));
52 | #endif
53 | WiFi.mode(WIFI_AP);
54 | #ifdef DEBUG
55 | Serial.print(F("[ INFO ] Configuring access point... "));
56 | #endif
57 |
58 | WiFi.softAPConfig(apip, apip, apsubnet);
59 |
60 | bool success;
61 | if (hidden)
62 | {
63 | success = WiFi.softAP(ssid, password, 3, true);
64 | }
65 | else
66 | {
67 | success = WiFi.softAP(ssid, password);
68 | }
69 | #ifdef DEBUG
70 | Serial.println(success ? F("Ready") : F("Failed!"));
71 | #endif
72 |
73 | if (success)
74 | {
75 | ledWifiOn();
76 | }
77 |
78 | #ifdef DEBUG
79 | IPAddress myIP = WiFi.softAPIP();
80 |
81 | Serial.print(F("[ INFO ] AP IP address: "));
82 | Serial.println(myIP);
83 | Serial.printf("[ INFO ] AP SSID: %s\n", ssid);
84 | #endif
85 | return success;
86 | }
87 |
88 | // Fallback to AP Mode, so we can connect to ESP if there is no Internet connection
89 | void ICACHE_FLASH_ATTR fallbacktoAPMode()
90 | {
91 | config.accessPointMode = true;
92 | #ifdef DEBUG
93 | Serial.println(F("[ INFO ] ESP-RFID is running in Fallback AP Mode"));
94 | #endif
95 | WiFi.mode(WIFI_AP);
96 | uint8_t macAddr[6];
97 | WiFi.softAPmacAddress(macAddr);
98 | char ssid[15];
99 | sprintf(ssid, "ESP-RFID-%02x%02x%02x", macAddr[3], macAddr[4], macAddr[5]);
100 | if (WiFi.softAP(ssid))
101 | {
102 | ledWifiOn();
103 | #ifdef DEBUG
104 | IPAddress myIP = WiFi.softAPIP();
105 |
106 | Serial.print(F("[ INFO ] AP IP address: "));
107 | Serial.println(myIP);
108 | Serial.printf("[ INFO ] AP SSID: %s\n", ssid);
109 | #endif
110 | }
111 | }
112 |
113 | // Try to connect Wi-Fi
114 | bool ICACHE_FLASH_ATTR connectSTA(const char *ssid, const char *password, byte bssid[6])
115 | {
116 | bool useBSSID = false;
117 | WiFi.mode(WIFI_STA);
118 | WiFi.persistent(false);
119 |
120 | if (!config.dhcpEnabled)
121 | {
122 | WiFi.config(config.ipAddress, config.gatewayIp, config.subnetIp, config.dnsIp);
123 | }
124 | #ifdef DEBUG
125 | Serial.print(F("[ INFO ] Trying to connect WiFi: "));
126 | Serial.println(ssid);
127 | Serial.print(F("[ INFO ] WiFi BSSID: "));
128 | #endif
129 | for (int i = 0; i < 6; i++)
130 | {
131 | #ifdef DEBUG
132 | Serial.print(bssid[i]);
133 | if (i < 5)
134 | Serial.print(F(":"));
135 | else
136 | Serial.println();
137 | #endif
138 | if (bssid[i] != 0)
139 | useBSSID = true;
140 | }
141 | if (useBSSID)
142 | {
143 | #ifdef DEBUG
144 | Serial.println(F("[ INFO ] BSSID locked"));
145 | #endif
146 | WiFi.begin(ssid, password, 0, bssid);
147 | }
148 | else
149 | {
150 | #ifdef DEBUG
151 | Serial.println(F("[ INFO ] any BSSID"));
152 | #endif
153 | WiFi.begin(ssid, password);
154 | }
155 | unsigned long now = millis();
156 | uint8_t timeout = 15; // define when to time out in seconds
157 | do
158 | {
159 | ledWifiStatus();
160 | delay(500);
161 | #ifdef DEBUG
162 | if (!WiFi.isConnected())
163 | Serial.print(F("."));
164 | #endif
165 | if (WiFi.isConnected())
166 | break;
167 | } while (millis() - now < timeout * 1000);
168 |
169 | // We now out of the while loop, either time is out or we connected. check what happened
170 | if (WiFi.isConnected())
171 | {
172 | String data = ssid;
173 | data += " " + WiFi.localIP().toString();
174 | writeEvent("INFO", "wifi", "WiFi is connected", data);
175 | return true;
176 | }
177 | else
178 | {
179 | #ifdef DEBUG
180 | Serial.println();
181 | Serial.println(F("[ WARN ] Couldn't connect in time"));
182 | #endif
183 | if (!config.fallbackMode)
184 | {
185 | #ifdef DEBUG
186 | Serial.println();
187 | Serial.println(F("[ INFO ] trying to reconnect to WiFi"));
188 | #endif
189 | wifiReconnectTimer.once(300, setEnableWifi);
190 | }
191 | return false;
192 | }
193 | }
194 |
195 | void ICACHE_FLASH_ATTR disableWifi()
196 | {
197 | wiFiUptimeMillis = 0;
198 | WiFi.disconnect(true);
199 | WiFi.softAPdisconnect(true);
200 | #ifdef DEBUG
201 | Serial.println(F("Turn wifi off."));
202 | #endif
203 | }
204 |
205 | void ICACHE_FLASH_ATTR enableWifi()
206 | {
207 | wiFiUptimeMillis = 0;
208 | if (config.accessPointMode)
209 | {
210 | startAP(config.accessPointIp, config.accessPointSubnetIp, config.networkHidden, config.ssid, config.wifiPassword);
211 | }
212 | else
213 | {
214 | bool connected = connectSTA(config.ssid, config.wifiPassword, config.bssid);
215 | if (!connected && config.fallbackMode)
216 | {
217 | fallbacktoAPMode();
218 | }
219 | }
220 | }
221 |
222 | void setupWifi(bool configured)
223 | {
224 | if (!configured)
225 | {
226 | WiFi.hostname("esp-rfid");
227 | fallbacktoAPMode();
228 | } else
229 | {
230 | wifiConnectHandler = WiFi.onStationModeConnected(onWifiConnect);
231 | wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);
232 | wifiOnStationModeGotIPHandler = WiFi.onStationModeGotIP(onWifiGotIP);
233 | WiFi.hostname(config.deviceHostname);
234 | enableWifi();
235 | }
236 | }
237 |
--------------------------------------------------------------------------------
/src/wsResponses.esp:
--------------------------------------------------------------------------------
1 | void ICACHE_FLASH_ATTR sendUserList(int page, AsyncWebSocketClient *client)
2 | {
3 | DynamicJsonDocument root(2048);
4 | root["command"] = "userlist";
5 | root["page"] = page;
6 | JsonArray users = root.createNestedArray("list");
7 | Dir dir = SPIFFS.openDir("/P/");
8 | int first = (page - 1) * 10;
9 | int last = page * 10;
10 | int i = 0;
11 | while (dir.next())
12 | {
13 | if (i >= first && i < last)
14 | {
15 | JsonObject item = users.createNestedObject();
16 | String uid = dir.fileName();
17 | uid.remove(0, 3);
18 | item["uid"] = uid;
19 | File f = SPIFFS.open(dir.fileName(), "r");
20 | size_t size = f.size();
21 | std::unique_ptr
buf(new char[size]);
22 | f.readBytes(buf.get(), size);
23 | DynamicJsonDocument json(512);
24 | auto error = deserializeJson(json, buf.get(), size);
25 | if (!error)
26 | {
27 | String username = json["user"];
28 | String pincode = "";
29 | if(json.containsKey("pincode"))
30 | {
31 | pincode = String((const char *)json["pincode"]);
32 | }
33 | for (int x = 1; x <= MAX_NUM_RELAYS; x++)
34 | {
35 | String theKey = String();
36 | if (x == 1)
37 | theKey = "acctype";
38 | else
39 | theKey = "acctype" + String(x);
40 | int AccType = json[theKey];
41 | item[theKey] = AccType;
42 | }
43 | unsigned long validsince = json.containsKey("validsince") ? json["validsince"] : 0;
44 | unsigned long validuntil = json["validuntil"];
45 | item["username"] = username;
46 | item["validsince"] = validsince;
47 | item["validuntil"] = validuntil;
48 | item["pincode"] = pincode;
49 | }
50 | }
51 | i++;
52 | yield();
53 | }
54 | float pages = i / 10.0;
55 | root["haspages"] = ceil(pages);
56 | size_t len = measureJson(root);
57 | AsyncWebSocketMessageBuffer *buffer = ws.makeBuffer(len);
58 | if (buffer)
59 | {
60 | serializeJson(root, (char *)buffer->get(), len + 1);
61 | if (client)
62 | {
63 | wsMessageTicker.once_ms_scheduled(50, [client, buffer]() {
64 | client->text(buffer);
65 | client->text("{\"command\":\"result\",\"resultof\":\"userlist\",\"result\": true}");
66 | });
67 | }
68 | else
69 | {
70 | ws.textAll("{\"command\":\"result\",\"resultof\":\"userlist\",\"result\": false}");
71 | }
72 | }
73 | }
74 |
75 | void ICACHE_FLASH_ATTR sendStatus(AsyncWebSocketClient *client)
76 | {
77 | struct ip_info info;
78 | FSInfo fsinfo;
79 | if (!SPIFFS.info(fsinfo))
80 | {
81 | #ifdef DEBUG
82 | Serial.print(F("[ WARN ] Error getting info on SPIFFS"));
83 | #endif
84 | }
85 | DynamicJsonDocument root(512);
86 | root["command"] = "status";
87 | root["heap"] = ESP.getFreeHeap();
88 | root["chipid"] = String(ESP.getChipId(), HEX);
89 | root["cpu"] = ESP.getCpuFreqMHz();
90 | root["sketchsize"] = ESP.getSketchSize();
91 | root["availsize"] = ESP.getFreeSketchSpace();
92 | root["availspiffs"] = fsinfo.totalBytes - fsinfo.usedBytes;
93 | root["spiffssize"] = fsinfo.totalBytes;
94 |
95 | int h = uptimeSeconds / 3600;
96 | int rem = uptimeSeconds % 3600;
97 | int m = rem / 60;
98 | int s = rem % 60;
99 | char uptimebuffer[9];
100 | sprintf(uptimebuffer, "%02d:%02d:%02d", h, m, s);
101 | root["uptime"] = uptimebuffer;
102 |
103 | root["version"] = VERSION;
104 | root["hostname"] = WiFi.hostname();
105 |
106 | if (config.accessPointMode)
107 | {
108 | wifi_get_ip_info(SOFTAP_IF, &info);
109 | struct softap_config conf;
110 | wifi_softap_get_config(&conf);
111 | root["ssid"] = String(reinterpret_cast(conf.ssid));
112 | root["dns"] = printIP(WiFi.softAPIP());
113 | root["mac"] = WiFi.softAPmacAddress();
114 | }
115 | else
116 | {
117 | wifi_get_ip_info(STATION_IF, &info);
118 | struct station_config conf;
119 | wifi_station_get_config(&conf);
120 | root["ssid"] = String(reinterpret_cast(conf.ssid));
121 | root["dns"] = printIP(WiFi.dnsIP());
122 | root["mac"] = WiFi.macAddress();
123 | }
124 |
125 | IPAddress ipaddr = IPAddress(info.ip.addr);
126 | IPAddress gwaddr = IPAddress(info.gw.addr);
127 | IPAddress nmaddr = IPAddress(info.netmask.addr);
128 | root["ip"] = printIP(ipaddr);
129 | root["gateway"] = printIP(gwaddr);
130 | root["netmask"] = printIP(nmaddr);
131 |
132 | size_t len = measureJson(root);
133 | AsyncWebSocketMessageBuffer *buffer = ws.makeBuffer(len);
134 | if (buffer)
135 | {
136 | serializeJson(root, (char *)buffer->get(), len + 1);
137 | if (client)
138 | {
139 | client->text(buffer);
140 | }
141 | else
142 | {
143 | ws.textAll(buffer);
144 | }
145 | }
146 | }
147 |
148 | void ICACHE_FLASH_ATTR printScanResult(int networksFound)
149 | {
150 | // sort by RSSI
151 | int n = networksFound;
152 | int indices[n];
153 | int skip[n];
154 | for (int i = 0; i < networksFound; i++)
155 | {
156 | indices[i] = i;
157 | }
158 | for (int i = 0; i < networksFound; i++)
159 | {
160 | for (int j = i + 1; j < networksFound; j++)
161 | {
162 | if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i]))
163 | {
164 | std::swap(indices[i], indices[j]);
165 | std::swap(skip[i], skip[j]);
166 | }
167 | }
168 | }
169 | DynamicJsonDocument root(512);
170 | root["command"] = "ssidlist";
171 | JsonArray scan = root.createNestedArray("list");
172 | for (int i = 0; i < 5 && i < networksFound; ++i)
173 | {
174 | JsonObject item = scan.createNestedObject();
175 | item["ssid"] = WiFi.SSID(indices[i]);
176 | item["bssid"] = WiFi.BSSIDstr(indices[i]);
177 | item["rssi"] = WiFi.RSSI(indices[i]);
178 | item["channel"] = WiFi.channel(indices[i]);
179 | item["enctype"] = WiFi.encryptionType(indices[i]);
180 | item["hidden"] = WiFi.isHidden(indices[i]) ? true : false;
181 | }
182 | size_t len = measureJson(root);
183 | AsyncWebSocketMessageBuffer *buffer = ws.makeBuffer(len); // creates a buffer (len + 1) for you.
184 | if (buffer)
185 | {
186 | serializeJson(root, (char *)buffer->get(), len + 1);
187 | ws.textAll(buffer);
188 | }
189 | WiFi.scanDelete();
190 | }
191 |
192 | void ICACHE_FLASH_ATTR sendTime(AsyncWebSocketClient *client)
193 | {
194 | DynamicJsonDocument root(512);
195 | root["command"] = "gettime";
196 | root["epoch"] = epoch;
197 | size_t len = measureJson(root);
198 | AsyncWebSocketMessageBuffer *buffer = ws.makeBuffer(len);
199 | if (buffer)
200 | {
201 | serializeJson(root, (char *)buffer->get(), len + 1);
202 | if (client)
203 | {
204 | client->text(buffer);
205 | }
206 | else
207 | {
208 | ws.textAll(buffer);
209 | }
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/tools/README.md:
--------------------------------------------------------------------------------
1 | # Tools
2 |
3 | Both tools can be found already built in the Github releases, if you don't want to install all the needed dependencies.
4 |
5 | If you want to modify the tools instead you need to install all the Node dependencies and hack your way around.
6 |
7 | On every push the binaries are generated by Github actions and if needed a new release should be published with the binaries.
8 |
9 | ## npm usage
10 |
11 | The web files located in src/websrc/ will be minified, combined (css, js), gzipped, converted to byte arrays, and these are placed in src/webh/ when the builder is run.
12 | To run the builder script with npm do as follows:
13 |
14 | 1. change directory into the webfilesbuilder folder
15 | 2. execute `npm install` in the webfilesbuilder folder to install the npm dependancies (listed in package.json)
16 | 3. execute `npm start` to run the web files builder script (gulpfile.js)
17 | 4. now you can compile the firmware using PlatformIO
18 |
19 | ## webfilesbuilder
20 |
21 | The `webfilesbuilder` executable that you can get from the releases should be copied in the `tools/webfilesbuilder/` folder and run from there as it looks for files in specific folders relative to that location.
--------------------------------------------------------------------------------
/tools/webfilesbuilder/bin.js:
--------------------------------------------------------------------------------
1 | const builder = require('./gulpfile.js').default;
2 |
3 | builder();
--------------------------------------------------------------------------------
/tools/webfilesbuilder/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp');
2 | const fs = require('fs-extra');
3 | const zlib = require('zlib');
4 | const concat = require('gulp-concat');
5 | const path = require('path');
6 | const htmlmin = require('gulp-htmlmin');
7 | const uglify = require('gulp-uglify');
8 | const websrc = '../../src/websrc/';
9 | const webh = `../../src/webh/`;
10 | const tpDir = `${websrc}3rdparty/`;
11 | const prDir = `${websrc}process/`;
12 | const fnDir = `${prDir}final/`;
13 | const gzDir = `${prDir}gzip/`;
14 | const directories = [
15 | websrc,
16 | webh,
17 | tpDir,
18 | prDir,
19 | fnDir,
20 | gzDir
21 | ];
22 | const mn = 'required';
23 |
24 | // Recreate output directories (destructive)
25 | const ensureDirs = (cb) => {
26 | console.log('RECREAT OUTPUT DIRECTORIES (destructive of: webh & process)');
27 | fs.removeSync(webh);
28 | fs.removeSync(prDir);
29 | directories.forEach(dir => {
30 | fs.ensureDirSync(dir);
31 | });
32 | cb();
33 | };
34 |
35 | // Minify JavaScript files
36 | function minify(srcFolder, destFolder) {
37 | return gulp.src(`${srcFolder}*.js`).pipe(uglify()).pipe(gulp.dest(destFolder));
38 | }
39 |
40 | // Concat files into a single file.
41 | function merge(srcFolder, fileType, destDir, outputFile) {
42 | return gulp.src(`${srcFolder}*.${fileType}`).pipe(concat({
43 | path: outputFile,
44 | stat: {
45 | mode: 0o666
46 | }
47 | })).pipe(gulp.dest(destDir));
48 | }
49 |
50 | // Gzip files
51 | function gzip(srcFile, destFile, cb) {
52 | const input = fs.readFileSync(srcFile);
53 | const output = zlib.gzipSync(input);
54 | fs.writeFileSync(destFile, output);
55 | cb();
56 | }
57 |
58 | // Create byte arrays of gzipped files
59 | function byteArray(source, destination, name, cb) {
60 | const arrayName = name.replace(/\.|-/g, "_");
61 | const data = fs.readFileSync(source);
62 | const wstream = fs.createWriteStream(destination);
63 | wstream.write(`#define ${arrayName}_len ${data.length}\n`);
64 | wstream.write(`const uint8_t ${arrayName}[] PROGMEM = {`);
65 | for (let i = 0; i < data.length; i++) {
66 | if (i % 1000 === 0)
67 | wstream.write('\n');
68 | wstream.write('0x' + data[i].toString(16).padStart(2, '0') + (i < data.length - 1 ? ',' : ''));
69 | }
70 | wstream.write('\n};');
71 | wstream.end(cb);
72 | }
73 |
74 | // Task: Process assets (scripts, UI scripts, HTML, styles, fonts)
75 | const process = (cb) => {
76 | console.log('PROCESS UI & 3RDPARTY FILES TO FINAL: minify, merge, copy');
77 | const mergeJS = () => merge(`${tpDir}js/`, 'js', `${fnDir}`, `${mn}.js`);
78 | const mergeCSS = () => merge(`${tpDir}css/`, 'css', `${fnDir}`, `${mn}.css`);
79 | const minifyUIjs = () => minify(`${websrc}js/`, `${fnDir}`);
80 | const minifyUIhtml = () => gulp.src(`${websrc}*.htm*`).pipe(htmlmin({ collapseWhitespace: true, minifyJS: true }).on('error', console.error)).pipe(gulp.dest(`${fnDir}`));
81 | const copyFonts = (cb) => { fs.copy(`${tpDir}fonts/`, `${fnDir}`, cb); };
82 | gulp.parallel(mergeJS, minifyUIjs, minifyUIhtml, mergeCSS, copyFonts)(cb);
83 | };
84 |
85 | // Task: Gzip files
86 | function gzipAll(cb) {
87 | console.log('GZIP FROM FINAL');
88 | const files = fs.readdirSync(fnDir);
89 | const tasks = files.map((file) => {
90 | const srcFile = path.join(fnDir, file);
91 | const destFile = path.join(gzDir, file + '.gz');
92 | const taskName = (done) => gzip(srcFile, destFile, done);
93 | Object.defineProperty(taskName, 'name', { value: `${file}.gz` });
94 | return taskName;
95 | });
96 | gulp.parallel(...tasks)(cb);
97 | }
98 |
99 | // Task: Create byte arrays from gzipped files
100 | function byteArrayAll(cb) {
101 | console.log('BYTE ARRAY FROM GZIP');
102 | const files = fs.readdirSync(gzDir);
103 | const tasks = files.map(file => {
104 | const srcFile = path.join(gzDir, file);
105 | const destFile = `${webh}${file}.h`;
106 | const taskName = (done) => byteArray(srcFile, destFile, file, done);
107 | Object.defineProperty(taskName, 'name', { value: `${file}.h` });
108 | return taskName;
109 | });
110 | gulp.parallel(...tasks)(cb);
111 | }
112 |
113 | // Main runner function
114 | function runner(cb) {
115 | gulp.series(ensureDirs, process, gzipAll, byteArrayAll)(cb);
116 | }
117 | exports.default = runner;
--------------------------------------------------------------------------------
/tools/webfilesbuilder/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webfilesbuilder",
3 | "version": "1.0.0",
4 | "description": "Combine all js and css files into one and gzip them for the ESP-RFID project",
5 | "scripts": {
6 | "start": "gulp"
7 | },
8 | "author": "ESP-RFID Developers",
9 | "license": "UNLICENSED",
10 | "dependencies": {
11 | "fs-extra": "^11.3.0",
12 | "gulp": "^5.0.0",
13 | "gulp-concat": "^2.6.1",
14 | "gulp-flatmap": "^1.0.2",
15 | "gulp-htmlmin": "^5.0.1",
16 | "gulp-uglify": "^3.0.2"
17 | },
18 | "bin": "bin.js"
19 | }
20 |
--------------------------------------------------------------------------------
/tools/wsemulator/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wsemulator",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "wsemulator",
9 | "version": "1.0.0",
10 | "license": "UNLICENSED",
11 | "dependencies": {
12 | "websocket": "^1.0.28",
13 | "ws": "^4.0.0"
14 | },
15 | "bin": {
16 | "wsemulator": "wserver.js"
17 | }
18 | },
19 | "node_modules/async-limiter": {
20 | "version": "1.0.0",
21 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
22 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
23 | },
24 | "node_modules/debug": {
25 | "version": "2.6.9",
26 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
27 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
28 | "dependencies": {
29 | "ms": "2.0.0"
30 | }
31 | },
32 | "node_modules/is-typedarray": {
33 | "version": "1.0.0",
34 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
35 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
36 | },
37 | "node_modules/ms": {
38 | "version": "2.0.0",
39 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
40 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
41 | },
42 | "node_modules/nan": {
43 | "version": "2.12.1",
44 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
45 | "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw=="
46 | },
47 | "node_modules/safe-buffer": {
48 | "version": "5.1.1",
49 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
50 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
51 | },
52 | "node_modules/typedarray-to-buffer": {
53 | "version": "3.1.5",
54 | "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
55 | "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
56 | "dependencies": {
57 | "is-typedarray": "^1.0.0"
58 | }
59 | },
60 | "node_modules/websocket": {
61 | "version": "1.0.28",
62 | "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.28.tgz",
63 | "integrity": "sha512-00y/20/80P7H4bCYkzuuvvfDvh+dgtXi5kzDf3UcZwN6boTYaKvsrtZ5lIYm1Gsg48siMErd9M4zjSYfYFHTrA==",
64 | "hasInstallScript": true,
65 | "dependencies": {
66 | "debug": "^2.2.0",
67 | "nan": "^2.11.0",
68 | "typedarray-to-buffer": "^3.1.5",
69 | "yaeti": "^0.0.6"
70 | },
71 | "engines": {
72 | "node": ">=0.10.0"
73 | }
74 | },
75 | "node_modules/ws": {
76 | "version": "4.1.0",
77 | "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
78 | "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
79 | "dependencies": {
80 | "async-limiter": "~1.0.0",
81 | "safe-buffer": "~5.1.0"
82 | }
83 | },
84 | "node_modules/yaeti": {
85 | "version": "0.0.6",
86 | "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
87 | "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=",
88 | "engines": {
89 | "node": ">=0.10.32"
90 | }
91 | }
92 | },
93 | "dependencies": {
94 | "async-limiter": {
95 | "version": "1.0.0",
96 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
97 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
98 | },
99 | "debug": {
100 | "version": "2.6.9",
101 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
102 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
103 | "requires": {
104 | "ms": "2.0.0"
105 | }
106 | },
107 | "is-typedarray": {
108 | "version": "1.0.0",
109 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
110 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
111 | },
112 | "ms": {
113 | "version": "2.0.0",
114 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
115 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
116 | },
117 | "nan": {
118 | "version": "2.12.1",
119 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
120 | "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw=="
121 | },
122 | "safe-buffer": {
123 | "version": "5.1.1",
124 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
125 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
126 | },
127 | "typedarray-to-buffer": {
128 | "version": "3.1.5",
129 | "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
130 | "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
131 | "requires": {
132 | "is-typedarray": "^1.0.0"
133 | }
134 | },
135 | "websocket": {
136 | "version": "1.0.28",
137 | "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.28.tgz",
138 | "integrity": "sha512-00y/20/80P7H4bCYkzuuvvfDvh+dgtXi5kzDf3UcZwN6boTYaKvsrtZ5lIYm1Gsg48siMErd9M4zjSYfYFHTrA==",
139 | "requires": {
140 | "debug": "^2.2.0",
141 | "nan": "^2.11.0",
142 | "typedarray-to-buffer": "^3.1.5",
143 | "yaeti": "^0.0.6"
144 | }
145 | },
146 | "ws": {
147 | "version": "4.1.0",
148 | "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
149 | "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
150 | "requires": {
151 | "async-limiter": "~1.0.0",
152 | "safe-buffer": "~5.1.0"
153 | }
154 | },
155 | "yaeti": {
156 | "version": "0.0.6",
157 | "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
158 | "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/tools/wsemulator/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wsemulator",
3 | "version": "1.0.0",
4 | "description": "Emulate websocket communication ",
5 | "main": "wserver.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "esp-rfid developers",
10 | "license": "UNLICENSED",
11 | "dependencies": {
12 | "websocket": "^1.0.28",
13 | "ws": "^4.0.0"
14 | },
15 | "bin": "wserver.js"
16 | }
17 |
--------------------------------------------------------------------------------