{"id":15043624,"url":"https://github.com/morzan1001/kiosk","last_synced_at":"2026-03-03T08:42:18.013Z","repository":{"id":255229554,"uuid":"848907795","full_name":"morzan1001/Kiosk","owner":"morzan1001","description":"Kiosk is a small software project that is intended to be a cash register system for a vending machine. ","archived":false,"fork":false,"pushed_at":"2025-04-14T08:38:56.000Z","size":1541,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-14T23:12:06.820Z","etag":null,"topics":["customtkinter","python","raspberry-pi"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/morzan1001.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-28T16:16:03.000Z","updated_at":"2025-04-14T08:38:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"e62e2156-e144-454d-9899-4957365919d8","html_url":"https://github.com/morzan1001/Kiosk","commit_stats":null,"previous_names":["morzan1001/kiosk"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morzan1001%2FKiosk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morzan1001%2FKiosk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morzan1001%2FKiosk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morzan1001%2FKiosk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/morzan1001","download_url":"https://codeload.github.com/morzan1001/Kiosk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248975329,"owners_count":21192210,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["customtkinter","python","raspberry-pi"],"created_at":"2024-09-24T20:49:21.236Z","updated_at":"2026-03-03T08:42:18.006Z","avatar_url":"https://github.com/morzan1001.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kiosk\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"/assets/logo.png\" alt=\"Logo\" width=\"250\" height=\"250\"\u003e\n\u003c/div\u003e\n\nKiosk 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.\n\n## 📋 Table of Contents\n\n- [🚀 Quick Start](#quick-start)\n- [✨ Features](#features)\n- [🛠️ Service](#service)\n- [🏢 Database](#database)\n- [💾 Backup](#backup)\n- [🔧 Components](#components)\n- [🤝 Contributing](#contributing)\n\n## 🚀 Quick Start\n\u003ca name=\"quick-start\"\u003e\u003c/a\u003e\n\nKiosk is a Python application and uses [CustomTkinter](https://github.com/TomSchimansky/CustomTkinter) as UI. I used [poetry](https://github.com/python-poetry/poetry) as a dependency manager. To start the application you can simply run `poetry install` and then `poetry run python3 src/main.py`.\n\nNormally 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](https://github.com/morzan1001/Kiosk/blob/main/config_example.json).\n\nIn order for the application to start, the [config_example.json](https://github.com/morzan1001/Kiosk/blob/main/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](https://github.com/morzan1001/Kiosk/blob/main/config_example.json). However, any adjustments can of course be made here. \n\n⚠️ **Important!**\n\nBoth the library for controlling the GPIO pins ([gpiod](https://pypi.org/project/gpiod/)) and the library for the pn532 NFC chip ([pn532lib](https://github.com/Liam-Deacon/py532lib)) 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.\n\n## ✨ Features\n\u003ca name=\"features\"\u003e\u003c/a\u003e\n\nThe 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.\n\n\u003cdiv align=\"middle\"\u003e\n    \u003cimg src=\"/assets/login_screen.png\" alt=\"Login\" height=\"200\"\u003e\n    \u003cimg src=\"/assets/card_screen.png\" alt=\"Shopping Card\" height=\"200\"\u003e \n\u003c/div\u003e\n\u003cbr/\u003e\n\nEach 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.\n\n\u003cdiv align=\"middle\"\u003e\n    \u003cimg src=\"/assets/admin_screen.png\" alt=\"Admin\" height=\"200\"\u003e\n    \u003cimg src=\"/assets/product_screen.png\" alt=\"Product\" height=\"200\"\u003e \n\u003c/div\u003e\n\u003cbr/\u003e\n\nAn admin can manage the stock and users and, of course, buy something themselves.\n\n### Future plans\n\nHere are a few ideas on how to expand the software:\n\n- 🎵 Play sounds on successful or unsuccessful checkout (✅)\n- 📊 More precise evaluation of the purchasing behavior of individual persons (✅ see [dashboard repository](https://github.com/morzan1001/Kiosk-Data-Frontend))\n- 📧 E-mail notifications for admins when product stock is low or for users when credit is low. (✅)\n- ...\n\n### 🎵 Sounds\n\nAs 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](https://github.com/morzan1001/Kiosk/blob/main/config_example.json#L37).\n\n### 📧 E-Mail\n\nThe 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](https://github.com/morzan1001/Kiosk/blob/main/config_example.json#L15). 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.\n\n### 🎺 Mattermost\n\nthe 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](https://github.com/morzan1001/Kiosk/blob/main/config_example.json#L21).\n\n## 🛠️ Service\n\u003ca name=\"service\"\u003e\u003c/a\u003e\n\nI use a service so that the kiosk software starts every time the Pi is started. My configuration looks like this:\n\n```ini\n[Unit]\nDescription=Kiosk\nAfter=graphical.target\n\n[Service]\nExecStart=/home/\u003cuser\u003e/.local/bin/poetry run python3 /home/\u003cuser\u003e/Kiosk/src/main.py\nWorkingDirectory=/home/\u003cuser\u003e/Kiosk\nUser=\u003cuser\u003e\nEnvironment=DISPLAY=:0\nRestart=always\n\n[Install]\nWantedBy=graphical.target\n```\n\nI 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.\n\n## 🏢 Database\n\u003ca name=\"database\"\u003e\u003c/a\u003e\n\nThanks to [sqlalchemy](https://www.sqlalchemy.org/), Kiosk gives you the freedom to choose which database you want to use. I started using a [sqlite](https://sqlite.org/) database, but have since switched to a [postgresql](https://www.postgresql.org/) database. In the [config.json](https://github.com/morzan1001/Kiosk/blob/main/config_example.json) you can select which database you want to use. [pgloader](https://pgloader.io/) can be used to perform a migration from sqlite to postgres. however, it is advisable to perform an alembic migration afterwards so that all settings (such as `autoincrement`) are also adopted. \n\n```bash\npgloader sqlite://src/database/kiosk.db  postgresql://kiosk:your_password_here@localhost/kiosk\n```\n\nIf you decide to use a [postgresql](https://www.postgresql.org/) database, it might also be worth taking a look at my [dashboard repository](https://github.com/morzan1001/Kiosk-Data-Frontend) for data analysis :grin:.\n\n## 💾 Backup\n\u003ca name=\"backup\"\u003e\u003c/a\u003e\n\nAs i have already painfully discovered, it makes sense to back up the database. \n\nI provide a script under [utils/db_backup.sh](https://github.com/morzan1001/Kiosk/blob/main/utils/db_backup.sh) with the name db_backup.sh which can be used to create database backups. The script creates a directory, checks whether a sqlite or a postgres database is used and then executes the corresponding backup routine. \n\nI call the script via cronjob to create a backup every day.\n\n```crontab\n0 2 * * * /home/\u003cuser\u003e/backup_script.sh \u003e\u003e /home/\u003cuser\u003e/backup.log 2\u003e\u00261\n```\n\nThe script ensures that I always have backups of the last 7 days and can simply restore them if the worst comes to the worst. \n\n## 🔧 Components\n\u003ca name=\"components\"\u003e\u003c/a\u003e\n\nI used the following components for my setup:\n\n- [Raspberry Pi 5](https://www.raspberrypi.com/products/raspberry-pi-5/) (In terms of performance, much older models also work, but the USB ports in the case may no longer fit well.)\n- [Display](https://www.raspberrypi.com/products/raspberry-pi-touch-display/)\n- [Display Cable](https://www.amazon.de/dp/B0CT5PZNRV?ref=ppx_yo2ov_dt_b_fed_asin_title) (Only needed when using a Pi 5)\n- [PN532 NFC reader](https://www.berrybase.de/pn532-nfc-und-rfid-modul-inkl.-karte-dongle)\n- [5V relay](https://www.berrybase.de/5v-1-kanal-relais-modul-mit-definierbarem-schaltsignal-high/low)\n- [Lock](https://www.amazon.de/dp/B07MWBHQNM?ref=ppx_yo2ov_dt_b_fed_asin_title)\n- [Barcode scanner](https://www.amazon.de/Tera-Kabelloser-Handheld-Barcode-Scanner-Akkustandsanzeige-Ergonomischem/dp/B078SQ91FB) (The barcode scanner is not absolutely necessary, if you want to use the barcode function, any USB barcode scanner will do.)\n\n### 📐 3D-Model\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"/assets/3d_model.png\" alt=\"3D-Model\" height=\"250\"\u003e\n\u003c/div\u003e\n\nI myself use an official Raspberry Pi display. The resolution of the software is adapted to this. In the folder [3D model](https://github.com/morzan1001/Kiosk/tree/main/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.\n\n## 🤝 Contributing\n\u003ca name=\"contributing\"\u003e\u003c/a\u003e\n\nContribution are very welcome, my software is not perfect and I am happy about everyone who wants to contribute something.\n\n### Dev hints\n\nI kept adding new features to this project and changing others. To make my life a little easier, especially with the database, I used [alembic](https://alembic.sqlalchemy.org/en/latest/). Alembic is not necessary to run the program or to develop for it but to make changes on an existing dataset it is great. \n\nTo 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:\n\n```ini\nsqlalchemy.url = sqlite:///src/database/kiosk.db\n```\nor \n```ini\nsqlalchemy.url = postgresql://kiosk:your_password_here@localhost:5432/kiosk\n``` \n\nThe `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](/assets/alembic_env_example.py). I think the alembic folder does not belong in the repo and therefore this file is located there separately. \n\nThe following command can be used to create an Alembic revision: \n\n```bash\nalembic revision --autogenerate -m \"Sync existing schema\"\n```\n\nAnd then to carry out the database migration: \n\n```bash\nalembic upgrade head\n```\n\nBy the way, if you've messed something up with your migrations, `alembic stamp head` is worth its weight in gold. :bowtie:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorzan1001%2Fkiosk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorzan1001%2Fkiosk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorzan1001%2Fkiosk/lists"}