Skip to content

Latest commit

 

History

History
184 lines (122 loc) · 9.23 KB

README.md

File metadata and controls

184 lines (122 loc) · 9.23 KB

Kiosk

Logo

Kiosk is a small software project that is intended to be a cash register system for a vending machine. Using a Raspberry Pi, an NFC reader and a lock, any fridge or cabinet can be transformed into a small vending machine for friends and colleagues.

📋 Table of Contents

🚀 Quick Start

Kiosk is a Python application and uses CustomTkinter as UI. I used poetry as a dependency manager. To start the application you can simply run poetry install and then poetry run python3 src/main.py.

Normally the logging of the application is set to INFO, but if something should fail at startup or during runtime, the logging can be set a little more finely. To do this, just change the loglevel in config.json.

In order for the application to start, the config_example.json must be renamed to config.json, it is not absolutely necessary to specify a mailserver, so the program should also start with the values from the config_example.json. However, any adjustments can of course be made here.

⚠️ Important!

Both the library for controlling the GPIO pins (gpiod) and the library for the pn532 NFC chip (pn532lib) can only be used on a raspberry pi. If you want to develop on another system, the corresponding parts of the software must be commented out or bypassed in some other way.

✨ Features

The kiosk is intended to be a small application to simplify the use of a communal refrigerator or other goods cupboard for a group of people.

Login Shopping Card

Each user is stored with an NFC ID. You can either use your own cards or dongles or use existing access cards or similar. A user can then select products using a barcode scanner and the costs are deducted from their (internal) account.

Admin Product

An admin can manage the stock and users and, of course, buy something themselves.

Future plans

Here are a few ideas on how to expand the software:

  • 🎵 Play sounds on successful or unsuccessful checkout (✅)
  • 📊 More precise evaluation of the purchasing behavior of individual persons
  • 📧 E-mail notifications for admins when product stock is low or for users when credit is low. (✅)
  • ...

🎵 Sounds

As no gag I have implemented that the kiosk can play sounds when a product is purchased or when a purchase fails. For this purpose, sound files can be specified in two folders. Once positive sounds and once negative sounds. the whole thing can be switched on and off in config.json.

📧 E-Mail

The kiosk can notify users when their account balance gets low, or administrators when a product stock is running low. In addition, the kiosk can send monthly statistics to users about their purchasing behavior. A corresponding SMTP server can be configured in config.json. If a user does not have a stored e-mail address in the database, he simply does not receive any e-mails, the field is not mandatory.

🎺 Mattermost

the kiosk can also notify users via a mattermost bot account. On the one hand, standard messages such as “low account balance” or for admins “low stock” are possible. On the other hand, short-term marketing messages can also be sent. The idea is that the kiosk regularly evaluates which users have bought little, on this basis individual users are offered a discount via mattermost that is valid for a certain time. the entire mattermost integration can be configured in config.json.

🛠️ Service

I use a service so that the kiosk software starts every time the Pi is started. My configuration looks like this:

[Unit]
Description=Kiosk
After=graphical.target

[Service]
ExecStart=/home/<user>/.local/bin/poetry run python3 /home/<user>/Kiosk/src/main.py
WorkingDirectory=/home/<user>/Kiosk
User=<user>
Environment=DISPLAY=:0
Restart=always

[Install]
WantedBy=graphical.target

I have stored this file under /etc/systemd/system/. As soon as the graphical user interface of Raspberry Pi OS has finished loading, the kiosk application starts.

💾 Backup

As i have already painfully discovered, it makes sense to back up the database. If you decide to use a Postgres, MariaDB or other SQL database, I recommend using the respective program such as pg_dump.

In my case I use a SQLite database. This is simply backed up via a cronjob. The script for this looks like this:

#!/bin/bash

# Path to the SQLite database file
DB_FILE="/home/<user>/Kiosk/src/database/kiosk.db"
BACKUP_DIR="/home/<user>/DB-Backup/"

# Create the backup directory if it doesn't exist
mkdir -p ${BACKUP_DIR}

# Set the filename for the backup
BACKUP_FILE="${BACKUP_DIR}/database_$(date +\%Y-\%m-\%d).db"

# Copy the database file
cp ${DB_FILE} ${BACKUP_FILE}

I call this script via cronjob once a day. Another script then takes care of deleting old backups. This script runs about an hour after the first one and looks like this:

#!/bin/bash

# Backup directory
BACKUP_DIR="/home/<user>/DB-Backup/"

# Find and delete backups older than 30 days
find ${BACKUP_DIR} -type f -name "*.db" -mtime +30 -exec rm {} \;

This ensures that I always have backups of the last 30 days and can simply restore them if the worst comes to the worst.

🔧 Components

I used the following components for my setup:

📐 3D-Model

3D-Model

I myself use an official Raspberry Pi display. The resolution of the software is adapted to this. In the folder 3D model you will find a model that offers space for a Pi as well as the display, an NFC reader and a 5V relay.

🤝 Contributing

Contribution are very welcome, my software is not perfect and I am happy about everyone who wants to contribute something.

Dev hints

I kept adding new features to this project and changing others. To make my life a little easier, especially with the database, I used alembic. Alembic is not necessary to run the program or to develop for it but to make changes on an existing dataset it is great.

To use alembic, alembic init alembic must be called once. This creates a directory with the name “alembic” in which the database revisions and configs are stored. In addition, an alembic.ini is placed in the root directory. In this ini, the database location can be specified as follows:

sqlalchemy.url = sqlite:///src/database/kiosk.db

The env.py must also be adapted in the alembic directory. I have saved an example of what this env.py can look like under assets. I think the alembic folder does not belong in the repo and therefore this file is located there separately.

The following command can be used to create an Alembic revision:

alembic revision --autogenerate -m "Sync existing schema"

And then to carry out the database migration:

alembic upgrade head

By the way, if you've messed something up with your migrations, alembic stamp head is worth its weight in gold. :bowtie: