This repository contains the code we are currently using to track laser usage for our membership, while this is still in the early stages with more features and better stability planned, it is fully usable and includes the following features:
- Gate user access based on credentials associated with their account (using a USB RFID reader and crosschecking against an access list)
- Activate and deactivate the Laser for cutting (using a teensy connected to the Laser Cutter)
- Periocally get an update for Laser usage (the Laser reports an odometer - in seconds - which we store on the teensy and check for updates)
- Track a user session to gather the amount of firing time the member used (this is uploaded to our database from which we generate invoices through a custom Wordpress plugin)
- Allow users to select which filter they are using
- Track filter usage against firing time and upload to our database for persistence
- Warn users when a filter requires changing
This project and its documentation are recommended for parties with intermediate-advanced technical knowledge due to its unfinished state, if you wish to implement it for your own makerspace / hackerspace we incourage you to make sure you are comfortable with Raspberry Pis, Linux, programmable microcontrollers, Python, basic electronics and have the ability to make your own APIs. We hope to be able to provide better documentation, install procedures and open source our API endpoints and Wordpress plugin in the future along side the stability improvements and additional features.
- API
- License
Ace laser FATT (Fob All The Things) app is a laser cutter access control system that allows Ace Makerspace to charge for laser cutting time and track filter usage. It enables users to log laser usage time, using RFID keys to authenticate which user is actively logged in.
The hardware used is a Raspberry Pi, a touch screen, an RFID reader, and a custom-built electronic laser cutter interface built upon a teensy microcontroller.
for more details about the commands see Installation
sudo apt-get update
sudo apt-get upgrade
cd ~
git clone https://github.com/acemonstertoys/ace_laser_fatt_app
cd ./ace_laser_fatt_app
pip install -r requirements.txt
touch prod.env
nano prod.env # add env variables here
sudo ln -s /home/pi/laserGui/systemd/kiosk.service /etc/systemd/system/kiosk.service
sudo systemctl daemon-reload
sudo systemctl enable kiosk.service
sudo systemctl start kiosk.service
# to stop run
sudo systemctl stop kiosk.service
# to stop disable
sudo systemctl disable kiosk.service
Bellow is instructions for preparing the Raspberry Pi, acquiring the app, configuring the app, as well as starting and stopping the app through the systemd service.
sudo apt-get update
sudo apt-get upgrade
Clone this repo into a directory named laserGui in the pi user's home directory. This path is referenced in the service that starts the app.
cd ~
git clone https://github.com/acemonstertoys/ace_laser_fatt_app
cd ./ace_laser_fatt_app
The laser GUI app is a python built on guizero, and as such it has a number of dependencies.
pip install -r requirements.txt
Key | Description | Default Value |
---|---|---|
ACE_ACCESS_URL | the access list URL | none, required |
ACE_EXPORT_TOKEN | used with ACE_ACCESS_URL | none, required |
ACEGC_ASSET_ID | the Assest ID of the pi | none, required |
ACEGC_ASSET_TOKEN | auth token | none, required |
ACEGC_BASE_URL | base URL to Grand Central | none, required |
ACEGC_LASER_COST | the cost in cents per minute of laser firing | 0.5 |
LASER_LOGOUT_TIME | number of inactivity minutes which invokes a logout | 40 |
LASER_ODO_POLLING | the time interval used to continously poll the laser for odometer reading, in seconds | 15 |
LASERGUI_SYNC_BUTTON | If present, will show a "Force Sync" button in the GUI | Off |
# [prod.env]
ACE_ACCESS_URL=
ACE_EXPORT_TOKEN=
ACEGC_ASSET_ID=
ACEGC_BASE_URL=
ACEGC_LASER_COST=
LASER_LOGOUT_TIME=
LASER_ODO_POLLING=
sudo ln -s /home/pi/laserGui/systemd/kiosk.service /etc/systemd/system/kiosk.service
sudo systemctl daemon-reload
sudo systemctl enable kiosk.service
sudo systemctl start kiosk.service
sudo systemctl stop kiosk.service
sudo systemctl disable kiosk.service
Name | Datatype | value |
---|---|---|
credential | String ( hex ) | see userDict['RFID'] |
authSuccess | Boolean | True/False |
member_id | String | see userDict['UID'] |
start_time | String | UTC String EX'2021-07-24 16:03:43.415006' |
end_time | String | UTC String EX'2021-07-24 16:03:43.415006' (python datetime.now()) |
start_odo | long (seconds) | Ex 0 |
end_odo | long (seconds) | EX: 0 laser.py laserInterface.odometer |
CURRENT_TIME | String | UTC String EX'2021-07-24 16:03:43.415006' |
Name | Datatype | value |
---|---|---|
filterId | long | |
filterType | Enum FilterType | |
--> GREEN_ORGANICS | long (minutes) | Green organics filters can be used for a total of 140 minutes |
--> WHITE_SYNTHETICS | long (minutes) | White synthetics filter can be used for a total of 60 minutes |
--> Unknown | long (minutes) | Unknown filter type |
recordedUsage | long | |
odometerReading | long (seconds) |
Pulls certified laser RFIDs from URL defined as an environment variable.
The json list contains only those user allowed to use the laser.
{
"headers":
{
"User-Agent": "Wget/1.20.1 (linux-gnu)"
},
"body":
{
"ace_export_token": <ACE_EXPORT_TOKEN>
}
}
// <LIST> returns the current list of users allowed to use the laser.
[
{
"RFID": <STRING>,
"First Name": <STRING>,
"Last Initial": <STRING upper case length 1> ,
"UID": <int>
},
{...}
,
....
]
Code | Description |
---|---|
200 | OK |
{
"headers":
{
"Authorization": "Token <ACEGC_ASSET_TOKEN>",
},
"body":
{
"access_point": <ACEGC_ASSET_ID> ,
"activity_date": <CURRENT_TIME (utc)>,
"credential": <credential>,
"success": <authSuccess>,
}
}
Code | Description |
---|---|
200 | OK |
{
"headers":
{
"Authorization": "Token <ACEGC_ASSET_TOKEN>",
},
"body":
{
"credential": <credential>,
"member_id": <member_id>,
"start_time": <start_time>,
"end_time": <end_time>,
"start_odo": <start_odo>,
"end_odo": <end_odo>,
}
}
Code | Description |
---|---|
200 | OK |
Creates a new filter in Grand Central
{
"header": {
'Authorization': "Token <ACEGC_ASSET_TOKEN>",
"Content-Type": "application/json"
},
"body": {
'seconds_used': 0,
'seconds_used': <totalUsage>,
'filter_type': <filterType>,
}
Code | Description |
---|---|
200 | OK |
Fetch existing filters from GC
header = {
"Authorization": "Token <ACEGC_ASSET_TOKEN>",
"Content-Type": "application/json"
}
requests.get("<ACEGC_BASE_URL>/filters/", headers=header)
{
"body": {
[ //list of filters
{
"filter_type": <filterType "O": "GREEN_ORGANICS","S":"WHITE_SYNTHETICS">,
},
...
]
}
}
Code | Description |
---|---|
200 | OK |
{
"header": {
"Authorization": "Token <ACEGC_ASSET_TOKEN>",
},
"body": {
"seconds_used": <totalUsage>,
}
}
Code | Description |
---|---|
200 | OK |
NOTE: the hardware is intended for experienced electrical engineers only. Your expected to build your own hardware interface with the laser you are using. We are only showing an example of how we've done ours.
The interface is documented here: https://github.com/acemonstertoys/laser-rfid
Item | Quantity |
---|---|
USB cable | 1 |
Raspberry Pi 3 | 1 |
Teensy 2.0 24 pin version | 1 |
Touch Screen (Raspberry Pi compatible) | 1 |
RFID Reader (USB) | 1 |
BC550 | 1 |
Graphical User Interace to the makerspace's laser.
- images — images used in the GUI
- systemd — Systemd service used to automatically start the GUI
- filter.py — represents laser filters
- laser.py — Interface to the Teensy controller (link TBD)
- laserGui.py — GUI built on guizero which wraps standard Python Tkinter GUI library.
- laserSession.py — represents a user's session at the laser.
- requirements.txt — python library dependencies
- sessionManager.py — manages interactions between the GUI and users and filters
Set the LASERGUI_ROOT
env variable to use a different install location for testing. If
this is not set, the default /home/pi/laserGui/
will be used.
Set the LASERGUI_MOCK
to use a mock Laser
class that will not try and talk
to the serial port but instead just do nothing. (This is pretty incomplete at the moment, but
it's enough to let the app run)
Made with contributors-img.
by oran collins
github.com/wisehackermonkey
[email protected]
20210717