This project consists of a server and ESP32 microcontroller with few modules to detect motion scan RFID UIDs and an active buzzer for audio feedback (when scanning UIDs).
-
ESP32
- It should have at least 1 5V pin
-
RC522 I2C RFID module
-
HC-SR501 PIR motion detector module
-
Active buzzer module (optional)
-
Computer to run the server on
-
Wires to connect the modules to the board
-
Source of power for the board
- SCL (Clock) -> IO22
- SDA (Output) -> IO21
- VCC -> 3V DC
- GND -> Ground
- OUT -> IO32
- VCC -> 5V DC
- GND -> Ground
- OUT -> IO33
- VCC -> 3V DC
- GND -> Ground
-
Install Bun
-
Clone the repository to a directory
git clone https://gitlab.fel.cvut.cz/kralji17/nsi-semestral-project.git
-
Open command line in that directory
-
Install server dependencies
bun i
-
Configure server by editing config.ts.
-
Start server
bun run server
- Optionally if editing the frontend (client) you can build the fronted using
bun run build
.
When logging into the web client you can create stations. Each station will have a token assigned which you can read in the web client. This token will have to configured including other network configurations such as Wi-Fi SSID and password and the configuration uploaded to the ESP32. The token serves as a form of identification, but also authotication for the ESP32 board so the server can discern one board from the others. To initially configure ESP32 you will need to install the PlatformIO set of CLI tools.
PlatformIO can be installed as na independent CLI utility regardless of what IDE or text editor are you using, but here the simplest way to getting PlatformIO will be described:
-
Install the VSCode text editor. (Unfortunately VSCodium won't work for this anymore.)
-
Install the C/C++ extension from VSCode extensions marketplace. PlatformIO will not work with other C/C++ extension than this one.
-
Install the PlatformIO extension from VSCode marketplace.
-
Open VSCode in the esp32 folder. You may have to wait a little bit while PlatformIO installs dependencies.
-
Edit the config.h header file with your values.
-
Connect the ESP32 to your computer
-
In VSCode go to "View -> Command Pallete" and start the task "PlatformIO: Upload"
If you encounter any errors I wish you good luck!
Path | Description | HTTP Method | Authorization header |
---|---|---|---|
/api/register | Register a new user | POST | none |
/api/auth-token | Request an authentication token that can be used in subsequent API requests that require authorization | GET | none |
/api/add-station | Add new station | POST | Bearer token |
/api/config-station | Configure a station | POST | Bearer token |
/api/delete-station | Deletee a station | POST | Bearer token |
/api/add-uid | Add new UID | POST | Bearer token |
/api/delete-uid | Delete a UID | POST | Bearer token |
/api/config-ntfy | Config ntfy notification push provider | POST | Bearer token |
/api/regenerate-ntfy-topic | Set ntfy topic to a new string randomly genrated by the server | POST | Bearer token |
export const uidAssignmentSchema = z.object({
uid: uidSchema,
assigned: z.boolean(),
});
export const ntfyConfigRequestSchema = z.object({
instance: z.string().max(512),
enabled: z.number(),
});
export const requestBodySchemas = {
register: z.object({
username: z.string().min(1).max(config.limits.usernameMaxLen),
password: z.string().min(1).max(config.limits.passwordMaxLen),
}),
addStation: z.object({
name: z.string().min(1).max(config.limits.stationNameMaxLen),
}),
addUid: z.object({
name: z.string().min(1).max(config.limits.uidNameMaxLen),
uid: z.string(),
}),
deleteStation: z.object({
token: z.string(),
}),
configStation: z.object({
token: z.string(),
uidAssignments: uidAssignmentSchema.array(),
}),
deleteUid: z.object({
id: z.number(),
}),
configNtfy: z.object({
config: ntfyConfigRequestSchema,
}),
} as const;
For /api/auth-token
request the following URL params are required:
Param | Type |
---|---|
username | string |
password | string |
:authToken
=gets replaced with the authentication token acquired from the api/auth-token
response.
Path | Description |
---|---|
/api/ws/client/events/:authToken | Subscribe to events of all station the user of this token has |
/api/ws/client/stations/:authToken | Subscribe to stations the user of this token has |
/api/ws/client/uids/:authToken | Subscribe to UIDs the user of this token has |
/api/ws/client/ntfy-config/:authToken | Subscribe to Ntfy configuration and its subsequent changes |
export const stationSchema = z.object({
id: z.number(),
name: z.string(),
token: z.string(),
});
// This extended version will be send to the websocket
export const detailedStationSchema = stationSchema.extend({
connected: z.boolean(),
uids: z.array(uidSchema),
});
export const reducedStationEventSchema = z.object({
type: z.number(),
timestamp: z.number(),
message: z.string().nullable(),
});
// This extended version will be send to the websocket
export const stationEventSchema = reducedStationEventSchema.extend({
id: z.number(),
stationId: z.number(),
});
export const uidSchema = z.object({
id: z.number(),
name: z.string(),
userId: z.number(),
value: z.string(),
});
export const ntfyConfigRequestSchema = z.object({
instance: z.string().max(512),
enabled: z.number(),
});
// This extended version will be send to the websocket
export const ntfyConfigSchema = ntfyConfigRequestSchema.extend({
topic: z.string().max(config.limits.ntfyTopicMaxLen),
});