Electronic door lock system for home automation. Besides the basic functionality (reading a key fob and opening the door) this project introduces the need for pin codes during a set night time and offers a web interface for managing keys and viewing logs.
Receives key fob readings and pin codes as strings of numbers seperate by newline via serialport. Opens the door by powering a GPIO pin. Runs on a Raspberry Pi Zero W.
This turned from a random project in to a portfolio tier skill show off using as much new and fancy tech as possible. Aims the be very typesafe. The project currently has two parts.
The backend for which Deno was a considered runtime but my knowledge and trust in Node was considerably higher so it ended up being the winner. For I/O operations the libraries serialport
and onoff
are used. To be TypeSafe with the database operations I chose to use the Prisma ORM. I've been recently hearing a lot about tRPC so I really wanted to use it for the API as it guarantees typesafety between the server and client using Zod, the library that goes where TypeScript doesn't, validating user input during runtime. Only the login router is a basic REST endpoint using Express to be able to use cookie based session token authentication. The tRPC API also uses a websocket handler for subscriptions to be able to stream new logs to the frontend.
The frontend which would have been a great show of my React skills but I ended up choosing between two new pieces of technology: Svelte and SolidJS. Solid won as it feels more closer to React and I've heard some friends talk about it. To accompany Solid I needed Solid Router and Solid tRPC. To save myself from writing CSS but still have full control over styling, the frontend needed Tailwind. And with Vite I'm able to move between iterations at the speed of light. For a mobile application the web frontend is an installable PWA.
Both of which are contained in this monorepo which uses amazing tools such as Yarn v3, Turborepo, Prettier and ESLint. As a DevOps enthusiastic I had to have CI/CD using GitHub actions. And for deployment we have Docker, so if it runs on my machine, it will run on your machine.
Use yarn and provided scripts
- To install dependencies
yarn
- To format code
yarn format
- To lint code
yarn lint
- To build and run
yarn dev
Copy server/.env.example
to server/.env
and add these values
Key | Value |
---|---|
NODE_ENV |
development |
MOCK_CONTROL_PORT |
Port for mock http control server |
MOCK_CONTROL_PASSWORD |
Password for mock control |
These will enable debug logs and mock the I/O so you don't need the actual hardware.
Start PostgreSQL in Docker
docker run --rm -d --name postgres -p 5432:5432 -e POSTGRES_USER=root -e POSTGRES_PASSWORD=password -e POSTGRES_DB=some_db postgres
Generate the Prisma client and sync the database with yarn workspace server prisma migrate dev
For more, refer to the Prisma docs.
Use the provided ./mock_input.sh
script, provide it a number as an argument.
Needs environmental variables from server/.env.example
which you can configure to your liking.
Needs a PostgreSQL database instance. A valid connection url needs to be used for the DATABASE_URL
environmental variable.
For access to hardware the container needs to be privileged or the devices can be passed manually. The serial device can be passed to the container via the --device
flag or docker-compose.yml
devices
field. And the GPIO pins can be added by mounting the entire /sys
directory inside the container.
The frontend is a simple container which just serves the SPA. It doesn't come with any HTTPS support nor proxying capability, yet the frontend will try to call the API paths /api/trpc
and /api/trpc_ws
both which will need to be proxied by an external reverse proxy such as Nginx to the corresponding ports in the backend container.
- Actually try deploying the docker containers (yeah, haven't tested them)
- Frontend
- Split dashboard into components (yes, it is over 300 lines)
- Make it pretty (graphic design ain't my passion)