├── .allstar
└── binary_artifacts.yaml
├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── contrib
├── README.md
└── startup-script
│ ├── README.md
│ └── makerspace-auth.service
├── docs
├── README.md
├── _config.yml
├── authboard-v1.0
│ ├── BOM.md
│ └── Soldering.md
├── authboard_v04.jpg
├── authboard_v10.jpg
├── client
│ └── Walkthrough.md
├── server
│ └── Protocol.md
└── tool-connection
│ ├── bofa_ad_base_1_oracle
│ ├── README.md
│ ├── board_back.jpg
│ ├── board_front.jpg
│ ├── board_mod.jpg
│ └── internal_wiring.jpg
│ ├── digital-logger-powerstrip
│ └── readme.md
│ └── epilog_mini_24
│ ├── README.md
│ ├── button_harness.jpg
│ ├── epilog_harness.jpg
│ ├── plates
│ ├── Makefile
│ ├── README.md
│ ├── one_box_mount_both.dxf
│ ├── one_box_mount_both.scad
│ ├── one_box_mount_both.svg
│ ├── one_box_mount_demo.png
│ ├── one_box_mount_demo.scad
│ ├── one_box_mount_front_hole_template.scad
│ ├── one_box_mount_front_hole_template.svg
│ ├── one_box_mount_hole_template.scad
│ ├── one_box_mount_hole_template.svg
│ ├── one_box_mount_inner.scad
│ ├── one_box_mount_inner.svg
│ ├── one_box_mount_lib.scad
│ ├── one_box_mount_lid_hole_template.scad
│ ├── one_box_mount_lid_hole_template.svg
│ ├── one_box_mount_outer.scad
│ ├── one_box_mount_outer.svg
│ ├── screenshot.png
│ ├── two_box_mount.png
│ ├── two_box_mount_demo.png
│ ├── two_box_mount_demo.scad
│ ├── two_box_mount_inner.scad
│ ├── two_box_mount_inner.svg
│ ├── two_box_mount_lib.scad
│ ├── two_box_mount_outer.scad
│ └── two_box_mount_outer.svg
│ ├── power_harness.jpg
│ └── shelf
│ ├── Makefile
│ ├── bracket_both.png
│ ├── bracket_both.scad
│ ├── bracket_both.stl
│ ├── bracket_clip.scad
│ ├── bracket_clip.stl
│ ├── bracket_in_box.jpg
│ ├── bracket_lib.scad
│ ├── bracket_main.scad
│ └── bracket_main.stl
├── hardware
├── README.md
├── box.jpg
├── pi-bracket-1
│ ├── README.md
│ ├── pibracket.jpg
│ ├── pibracket.stl
│ └── piclip.stl
└── pi-hat-1
│ ├── Makefile
│ ├── README.md
│ ├── board.png
│ ├── buttonwiring.jpg
│ ├── crimping1.jpg
│ ├── crimping2.jpg
│ ├── crimping3.jpg
│ ├── crimping4.jpg
│ ├── crimping5.jpg
│ ├── fp-info-cache
│ ├── fp-lib-table
│ ├── gerber
│ ├── ms_auth_breakout-B_Adhes.gbr
│ ├── ms_auth_breakout-B_CrtYd.gbr
│ ├── ms_auth_breakout-B_Fab.gbr
│ ├── ms_auth_breakout-B_Mask.gbr
│ ├── ms_auth_breakout-B_Paste.gbr
│ ├── ms_auth_breakout-B_SilkS.gbr
│ ├── ms_auth_breakout-Bottom.gbr
│ ├── ms_auth_breakout-Cmts_User.gbr
│ ├── ms_auth_breakout-Dwgs_User.gbr
│ ├── ms_auth_breakout-Eco1_User.gbr
│ ├── ms_auth_breakout-Eco2_User.gbr
│ ├── ms_auth_breakout-Edge_Cuts.gbr
│ ├── ms_auth_breakout-F_Adhes.gbr
│ ├── ms_auth_breakout-F_CrtYd.gbr
│ ├── ms_auth_breakout-F_Fab.gbr
│ ├── ms_auth_breakout-F_Mask.gbr
│ ├── ms_auth_breakout-F_Paste.gbr
│ ├── ms_auth_breakout-F_SilkS.gbr
│ ├── ms_auth_breakout-Margin.gbr
│ ├── ms_auth_breakout-NPTH-drl-drl_map.pdf
│ ├── ms_auth_breakout-NPTH-drl.gbr
│ ├── ms_auth_breakout-PTH-drl-drl_map.pdf
│ ├── ms_auth_breakout-PTH-drl.gbr
│ └── ms_auth_breakout-Top.gbr
│ ├── ms_auth_breakout-cache.lib
│ ├── ms_auth_breakout.csv
│ ├── ms_auth_breakout.dcm
│ ├── ms_auth_breakout.kicad_pcb
│ ├── ms_auth_breakout.lib
│ ├── ms_auth_breakout.pdf
│ ├── ms_auth_breakout.pretty
│ ├── 2X20.kicad_mod
│ ├── BUCK_HORIZONTAL.kicad_mod
│ ├── C1206.kicad_mod
│ ├── CERT-SMALL-SILK.kicad_mod
│ ├── CHIPLED_0805.kicad_mod
│ ├── DO-214AC.kicad_mod
│ ├── HFD23.kicad_mod
│ ├── MOLEX-1X2_LOCK.kicad_mod
│ ├── MOLEX-1X3_LOCK.kicad_mod
│ ├── MOLEX-1X4_LOCK.kicad_mod
│ ├── MOLEX-1X5_LOCK.kicad_mod
│ ├── MOLEX-1X6_LOCK.kicad_mod
│ ├── MS_LOGO_VECTOR.kicad_mod
│ ├── OSHW-LOGO-M.kicad_mod
│ ├── POWER_JACK_PTH_LOCK.kicad_mod
│ ├── R0805.kicad_mod
│ ├── SO16.kicad_mod
│ └── SOT23-3.kicad_mod
│ ├── ms_auth_breakout.pro
│ ├── ms_auth_breakout.sch
│ ├── plots-pdf
│ ├── ms_auth_breakout-B_Mask.pdf
│ ├── ms_auth_breakout-B_SilkS.pdf
│ ├── ms_auth_breakout-Bottom.pdf
│ ├── ms_auth_breakout-Edge_Cuts.pdf
│ ├── ms_auth_breakout-F_Mask.pdf
│ ├── ms_auth_breakout-F_SilkS.pdf
│ └── ms_auth_breakout-Top.pdf
│ └── sym-lib-table
└── software
├── LICENSE
├── Makefile
├── README.md
├── authbox
├── __init__.py
├── api.py
├── badgereader_hid_keystroking.py
├── badgereader_wiegand_gpio.py
├── compat.py
├── config.py
├── fake_evdev_device_for_testing.py
├── fake_gpio_for_testing.py
├── gpio_button.py
├── gpio_buzzer.py
├── gpio_relay.py
├── tests
│ ├── __init__.py
│ ├── __main__.py
│ ├── setup_mock_pin_factory.py
│ ├── test_api.py
│ ├── test_badgereader_hid_keystroking.py
│ ├── test_badgereader_wiegand_gpio.py
│ ├── test_config.py
│ ├── test_gpio_button.py
│ ├── test_gpio_buzzer.py
│ ├── test_gpio_relay.py
│ └── test_timer.py
└── timer.py
├── lockbox.ini
├── lockbox.py
├── qa.ini
├── qa.py
├── requirements-dev.txt
├── sample_auth_check.sh
├── sample_deauth.sh
├── sample_extend.sh
├── setup.cfg
├── setup.py
├── test_qa.py
├── test_two_button.py
├── two_button.ini
└── two_button.py
/.allstar/binary_artifacts.yaml:
--------------------------------------------------------------------------------
1 | # Exemption reason: This repo contains text-based Kicad .lib files which are falsely identified as executable binaries.
2 | # Exemption timeframe: permanent
3 | optConfig:
4 | optOut: true
5 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 | on:
3 | push:
4 | branches:
5 | - master
6 | tags:
7 | - v*
8 | pull_request:
9 |
10 | jobs:
11 | authbox-test:
12 | runs-on: ${{ matrix.os }}
13 | strategy:
14 | fail-fast: false
15 | matrix:
16 | python-version: [2.7, 3.6, 3.7]
17 | os: [ubuntu-latest]
18 |
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v1
22 | - name: Set Up Python ${{ matrix.python-version }}
23 | uses: actions/setup-python@v1
24 | with:
25 | python-version: ${{ matrix.python-version }}
26 | - name: Install
27 | run: |
28 | python -m pip install --upgrade pip
29 | cd software
30 | make setup
31 | pip install -U .
32 | - name: Test
33 | run: cd software && make test
34 |
35 | authbox-lint:
36 | runs-on: ${{ matrix.os }}
37 | strategy:
38 | fail-fast: false
39 | matrix:
40 | python-version: [3.6]
41 | os: [ubuntu-latest]
42 |
43 | steps:
44 | - name: Checkout
45 | uses: actions/checkout@v1
46 | - name: Set Up Python ${{ matrix.python-version }}
47 | uses: actions/setup-python@v1
48 | with:
49 | python-version: ${{ matrix.python-version }}
50 | - name: Install
51 | run: |
52 | python -m pip install --upgrade pip
53 | cd software
54 | make setup
55 | pip install -U .
56 | - name: Lint
57 | run: cd software && make lint
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .*.sw[op]
2 | *~
3 |
4 | *.py[co]
5 |
6 | *.b#?
7 | *.s#?
8 | *.l#?
9 | *.epf
10 |
11 | .DS_Store
12 |
13 | *.bak
14 | cover
15 | .coverage
16 | .venv
17 | .tox
18 | build
19 | dist
20 | *.egg-info
21 |
22 | # ignore files called out in sample_auth_check.sh to avoid issues
23 | authorized.txt
24 | log.txt
25 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to any Google project must be accompanied by a Contributor License
9 | Agreement. This is necessary because you own the copyright to your changes, even
10 | after your contribution becomes part of this project. So this agreement simply
11 | gives us permission to use and redistribute your contributions as part of the
12 | project. Head over to to see your current
13 | agreements on file or to sign a new one.
14 |
15 | You generally only need to submit a CLA once, so if you've already submitted one
16 | (even if it was for a different project), you probably don't need to do it
17 | again.
18 |
19 | ## Code reviews
20 |
21 | All submissions, including submissions by project members, require review. We
22 | use GitHub pull requests for this purpose. Consult [GitHub Help] for more
23 | information on using pull requests.
24 |
25 | [GitHub Help]: https://help.github.com/articles/about-pull-requests/
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | 
4 |
5 | We started this project with two goals in mind, for Google makerspaces where
6 | employees all have the same kind of RFID badge:
7 |
8 | 1. Only people authorized (trained) should be able to use dangerous tools
9 | 2. We'd like to have reliable access logs for even non-dangerous tools
10 |
11 | ## Organization
12 |
13 | docs/
14 | Documentation on the project to include contributions on tool connectivity.
15 | software/
16 | The Python client that runs on a Pi.
17 | hardware/
18 | The custom Pi hat we use to interact with buttons and a power switch tail.
19 |
20 | ## Contributing
21 |
22 | We *welcome* contributions, especially ones that make this more useful to other
23 | makerspaces. We'd like this to be a generic solution wherever possible.
24 |
--------------------------------------------------------------------------------
/contrib/README.md:
--------------------------------------------------------------------------------
1 | # Contrib
2 |
3 | ## About
4 |
5 | Contributed scripts and utilities which are not maintained by the
6 | `makerspace-auth` authors.
7 |
8 | These are presented here for reference, inspiration, or other community lead
9 | guidance.
10 |
--------------------------------------------------------------------------------
/contrib/startup-script/README.md:
--------------------------------------------------------------------------------
1 | # Startup Script
2 |
3 | ## About
4 |
5 | In this directory is a Systemd [Service][systemd.service] Unit focused on the
6 | setup running of the Makerspace Auth code on the Raspberry Pi.
7 |
8 | ## Installation
9 |
10 | After configuration (see below) this script should be placed in
11 | `/etc/systemd/system` named `makerspace-auth.service`.
12 |
13 | If, after creating the file at that location, changes are desired the user will
14 | need to reload the file (`systemctl daemon-reload`) to refresh any relevant
15 | changes.
16 |
17 | After copying the file to `/etc/systemd/system` it can be started by running:
18 |
19 | ```
20 | systemctl start makerspace-auth
21 | ```
22 |
23 | It can also be set to automatically start on boot by running:
24 |
25 | ```
26 | systemctl enable makerspace-auth
27 | ```
28 |
29 | Fore more information read the [systemd] documentation.
30 |
31 | ## Configuration
32 |
33 | For most users there is only a single option which will need to be changed:
34 | the name of the script to be called on the `ExecStart` line. In this example it
35 | calls the `doorauth.py` script located in the `/software` subdirectory of the
36 | repository.
37 |
38 |
39 | The other options in the script handle the following:
40 |
41 |
42 | | option | purpose |
43 | | --- | --- |
44 | | Type=simple | Expect the unit to run in the foreground, allowing systemd to directly detect if the unit has stopped (and then restart it) |
45 | | ExecStart=/usr/bin/python doorauth.py | Fully qualified path to be executed |
46 | | WorkingDirectory=/home/pi/makerspace-auth/software | Use this path as the working directory when running the unit |
47 | | User=pi | Run the unit as the `pi` user |
48 | | Group=pi | Run the unit as the `pi` group |
49 | | Restart=always | Always attempt to restart the unit if it stops (except when stopped by an administrator with `systemctl` |
50 | | RestartSec=2s | Insert a 2 second delay in between restart attempts |
51 | | Environment=PYTHONUNBUFFERED=true | Do not buffer output, instead immediately flush it to the journal |
52 | | NoNewPrivileges=true | Do not allow our unit to gain new privileges via SETUID, SETUID, or other filesystem capabilities |
53 | | ProtectSystem=full | Ensure that `/usr`, `/lib`, and `/etc/` are seen as read-only by our unit |
54 | | RestrictRealtime=true | Do not allow the process to change it's kernel scheduling to realtime mode |
55 | | StandardOutput=journal | Ensure all output from `STDOUT` ends up in the systemd journal |
56 | | StandardError=journal | Ensure all output from `STDERR` ends up in the systemd journal |
57 |
58 |
59 |
60 |
61 | [systemd.service]: https://www.freedesktop.org/software/systemd/man/systemd.service.html
62 | [systemd]: https://www.freedesktop.org/wiki/Software/systemd/
63 |
--------------------------------------------------------------------------------
/contrib/startup-script/makerspace-auth.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Makerspace Auth RFID system
3 | Documentation=https://github.com/google/makerspace-auth/blob/master/README.md
4 |
5 | [Service]
6 | Type=simple
7 | ExecStart=/usr/bin/python doorauth.py
8 | WorkingDirectory=/home/pi/makerspace-auth/software
9 | User=pi
10 | Group=pi
11 | Restart=always
12 | RestartSec=2s
13 | Environment=PYTHONUNBUFFERED=true
14 |
15 | # Restrict system mechanisms which are unneeded by Makerspace Auth
16 | NoNewPrivileges=true
17 | ProtectSystem=full
18 | RestrictRealtime=true
19 |
20 | StandardOutput=journal
21 | StandardError=journal
22 |
23 | [Install]
24 | WantedBy=multi-user.target
25 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ## Makerspace Auth
2 |
3 | Like most makerspaces, we need to ensure that people have taken training before
4 | using dangerous tools. This is the Authbox, a project that we're sharing with
5 | the community and welcoming contributions that help it work with more tools.
6 |
7 | ### Assembling your Authboard 1.0
8 |
9 | * [authboard-v1.0/BOM.md](authboard-v1.0/BOM.md)
10 | * [authboard-v1.0/Soldering.md](authboard-v1.0/Soldering.md)
11 |
12 | 
13 |
14 | ### Connecting tools
15 |
16 | * [tool-connection/epilog\_mini\_24/](tool-connection/epilog_mini_24)
17 | * [tool-connection/bofa\_ad\_base\_1\_oracle/](tool-connection/bofa_ad_base_1_oracle)
18 |
19 | ### Connecting to servers
20 |
21 | * [server/Protocol.md](server/Protocol.md)
22 |
23 | ### Client software
24 |
25 | * [client/Walkthrough.md](client/Walkthrough.md)
26 |
27 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/docs/authboard-v1.0/BOM.md:
--------------------------------------------------------------------------------
1 | | Refdes | MFN | MPN | Value |
2 | | ------ | --- | --- | ----- |
3 | | C2 | Taiyo Yuden | MK316BBJ476ML-T | 47u |
4 | | D1-D4 | Micro Commercial Co | SS14FL-TP | 1A |
5 | | IC1 | TI | ULN2003ADR |
6 | | J10,J12-J13 | Molex | 22-23-2021 |
7 | | J11 | ? | Buck Module | 5V SJ |
8 | | J14 | Sullins | SFH11-PBPC-D20-ST-BK |
9 | | J1-J4 | Molex | 22-23-2051 |
10 | | J5 | Molex | 22-23-2061 |
11 | | J7 | Molex | 22-23-2031 |
12 | | J8 | Molex | 22-23-2041 |
13 | | J9 | Wurth | 694106301002 |
14 | | LED1-LED2 | LG | LG R971-KN-1 |
15 | | Q1-Q6 | Diodes Incorporated | DMN3023L-7 |
16 | | R1 | Yaego | RC0805JR-071KL |
17 | | R2 | Yaego | RC0805JR-07560RL |
18 | | R3-R6 | Yaego | RC0805JR-0710KL |
19 | | RL1-RL2 | Omron | G5V-1-DC12 |
20 |
--------------------------------------------------------------------------------
/docs/authboard-v1.0/Soldering.md:
--------------------------------------------------------------------------------
1 | ## General Assembly
2 |
3 | This involves a good amount of SMT soldering. If you've never done it before, watch [this video](https://www.youtube.com/watch?v=_kNTFCuy4xk) I threw together. The first rule I'll give you with is that any pin can take 2 seconds of heat without damage at normal temperatures (up to 700 deg F). More than that is at your own risk. The second is that generally the numbers on these parts face up.
4 |
5 | The parts that might burn out due to overcurrent are on the bottom of the board -- worse for automated assembly, much better for replacing after a failure. I'd suggest roughly this order of assembly:
6 |
7 | * R1, LED1 (touch with a bench supply to GND, 12V and confirm light)
8 | * R2, LED2 (touch with a bench supply to GND, OUT and confirm light)
9 | * D1, D2, C2
10 |
11 | Take a break. You're done with the top-side 2-pin SMT.
12 |
13 | * R3-R6 (bottom side)
14 | * IC1, bottom side observing polarity (for the most clearance, this is first).
15 | * Q1-Q6, bottom side
16 | * JP1 (40-pin header, which is inserted from bottom side and soldered on top). No keying on the Raspbery Pi GPIOs so it doesn't matter which way you place this.
17 |
18 | Take another break.
19 |
20 | * J11 (buck module) with ADJ trace cut and 5V solder jumper closed. Install and test without a Pi, and with a bench supply at 12V: You should get 5V on output and not hit a 100mA current limit.
21 | * Remaining J connectors, being careful that they are installed straight.
22 |
--------------------------------------------------------------------------------
/docs/authboard_v04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/authboard_v04.jpg
--------------------------------------------------------------------------------
/docs/authboard_v10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/authboard_v10.jpg
--------------------------------------------------------------------------------
/docs/client/Walkthrough.md:
--------------------------------------------------------------------------------
1 | ## Dependencies
2 |
3 | * gpiozero
4 | * python evdev
5 |
6 | ## Loading hardware objects
7 |
8 | There's a basic launcher script, e.g. `two_button.py`. This script should only contain the business logic, and high level interface.
9 |
10 | Hardware itself is enabled through the ini file. For example:
11 |
12 | [pins]
13 | on_button = Button:11:38
14 |
15 | This enables the code in the launcher script to load some number of devices to use as an enabling button (the name is arbitrary):
16 |
17 | class Dispatcher(BaseDispatcher):
18 | def __init__(self, config):
19 | super(Dispatcher, self).__init__(config)
20 | ...
21 | self.load_config_object('on_button', on_down=self.on_button_down)
22 |
23 | Then whenever necessary, you can call
24 |
25 | self.on_button.blink()
26 | # or
27 | self.on_button.off()
28 |
29 | to change its light, or in
30 |
31 | def on_button_down(self, source):
32 | print "Button pressed"
33 |
34 | ## Multiple hardware for one action
35 |
36 | Simple! It's a list.
37 |
38 | [pins]
39 | enable_output = Relay:ActiveHigh:29
40 | # or
41 | enable_output = Relay:ActiveHigh:29, Relay:ActiveHigh:31
42 |
43 |
44 | ## Threading model
45 |
46 | Each hardware device (button, buzzer, etc) may start its own thread, but events are delivered in one main thread for ease of programming.
47 |
48 | ## Running on boot
49 |
50 | The simplest way is adding an `@reboot cd /path/to/source; python two_button.py` to `crontab -e`. You can also make a systemd unit, if your distro supports that.
51 |
52 | ## More reading
53 |
54 | See `qa.py` or `two_button.py` for examples of how this can be used.
--------------------------------------------------------------------------------
/docs/server/Protocol.md:
--------------------------------------------------------------------------------
1 | ## HTTP API
2 |
3 | /api/v1/
4 |
5 | Params:
6 |
7 | * location
8 | * tool
9 | * badge\_id
10 | * state=initial,extend,cancel
11 | * auth\_minutes (number)
12 |
13 | Requests should also authenticated, for example with an `api_key` param, or by
14 | ssl client cert.
15 |
16 | The server can make assumptions about the total authorized time, for example if
17 | requests like this happen:
18 |
19 | * `auth_minutes=30,state=initial` at t=0
20 | * `auth_minutes=30,state=extend` at t=22
21 |
22 | That the total authorized time for usage stats is only 22+30 minutes.
23 |
24 | This API requires the client to only store minimal state -- the `badge_id`
25 | (which must be re-sent), and whether a session is in progress to differentiate
26 | `initial` vs `extend`.
27 |
--------------------------------------------------------------------------------
/docs/tool-connection/bofa_ad_base_1_oracle/README.md:
--------------------------------------------------------------------------------
1 | ## BOFA AD Base 1 Oracle Connection
2 |
3 | The easiest way to drive this is volt-free from J12 or J13. Otherwise you can
4 | use 12V from any of the buttons or J7, but check polarity.
5 |
6 | ## Volt-free input
7 |
8 | | Item | Qty |
9 | | ---------------------- | --- |
10 | | #24 wire 2 cond x 330cm (McMaster 9290T31)| 1 |
11 | | 25mm 3/16" heat shrink | 2 |
12 | | white ferrules | 2 |
13 | | KK pin | 2 |
14 | | KK 2p housing | 1 |
15 | | Black zip tie | 10 |
16 |
17 | Remove power. Open door using T20 torx driver. (These screws are captive, but
18 | difficult to get started when you close it up again.)
19 |
20 | Remove knockout on back of machine near power switch. Feed ferrule side of
21 | cable though. Follow existing wire path in corner of machine up through the
22 | door.
23 |
24 | 
25 |
26 | Marked with lines in the photo above, there are two Phoenix blocks on the right
27 | side of the circuit board both labeled "RUN". The one on the 4-pin block ships
28 | with a red jumper wire. Remove that jumper wire and screw the ferrule end
29 | instead. (Polarity does not matter.)
30 |
31 | 
32 |
33 | Remove the board and solder a small piece of wire across the standby switch
34 | (SW3), or between the nearby vias from back (above text "STANDBY" and to the
35 | right of text "IC8", marked with circles in the first photo above).
36 |
37 | 
38 |
39 | Once length is right, secure wire along with the existing bundle using zip ties.
40 | On the outside, this cable has a vertical free run, then snakes under the Epilog
41 | behind the rear foot, and through the plate's ziptie mount.
42 |
43 | 
44 |
45 | TODO: Exterior routing diagram.
46 |
47 | TODO: Include knockout protector stl with cable clamp.
48 |
49 | ## 12V Input
50 |
51 | Same as above, but you will additionally need
52 |
53 | | Item | Qty |
54 | | ---------------------- | --- |
55 | | KK 3p housing | 1 |
56 | | 2p Phoenix block | 1 |
57 |
58 | Switch to 3-pin KK housing and use on J7 (safest), or 5-pin and use on a button
59 | output (probably ok, assuming BOFA board includes protection diode). Install
60 | this in the 2-pin RUN, and mind polarity.
61 |
62 | ## Blocked sensor
63 |
64 | There are relay outputs that trigger at 75% or fully blocked. These are at the
65 | bottom of the board, but we have not experimented with their use.
66 |
--------------------------------------------------------------------------------
/docs/tool-connection/bofa_ad_base_1_oracle/board_back.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/bofa_ad_base_1_oracle/board_back.jpg
--------------------------------------------------------------------------------
/docs/tool-connection/bofa_ad_base_1_oracle/board_front.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/bofa_ad_base_1_oracle/board_front.jpg
--------------------------------------------------------------------------------
/docs/tool-connection/bofa_ad_base_1_oracle/board_mod.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/bofa_ad_base_1_oracle/board_mod.jpg
--------------------------------------------------------------------------------
/docs/tool-connection/bofa_ad_base_1_oracle/internal_wiring.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/bofa_ad_base_1_oracle/internal_wiring.jpg
--------------------------------------------------------------------------------
/docs/tool-connection/digital-logger-powerstrip/readme.md:
--------------------------------------------------------------------------------
1 | In order to add support for the Digital Loggers IoT relay (https://www.digital-loggers.com/iotfaqs.html), make the following changes:
2 |
3 | 1: Attach the positive lead to pin 1 of J7 (the pin closest to the J12/J13 relays) and the negative lead to J7 pin 2.
4 |
5 | 2: Update the software/two_button.ini config file so that the default line 39 now reads " enable_output = Relay:ActiveHigh:40 ".
6 |
7 | 3: Verify pins 1 and 2 alternate from 12v to 0v with a multimeter, as you actuate the buttons.
8 |
9 |
10 |
11 | Note: Other ports may be workable as well, depending on what you have attached to your hat. Look at hardware/pi-hat-1/ms_auth_breakout.pdf for the full trace.
12 | J7 is the simplest (the high current relay, ~1A at 12V), but J1-5 may be workable as well (using pin 4 and pin 1 for BN_Logic as a relay). This is untested.
13 | In a pinch, J8 may also work if you're not using an RGB light.
14 |
15 | Note that J12/13 do not work, as they are the volt free switches and the IoT relay expects a 3-60V DC signal.
16 |
17 | Also note that polarity matters, so be sure you're sending +12V to the IoT relay.
18 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/README.md:
--------------------------------------------------------------------------------
1 | ## Mini 24 Connection
2 |
3 | There are quite a few subcomponents here, but the gist of it is we interrupt the
4 | front door interlock unless you've successfully badged in.
5 |
6 | ### Mounting plates
7 |
8 | Cut these out of 6mm MDF or acrylic. You'll need the following parts to attach
9 | your box:
10 |
11 |
12 |
13 | * [inner plate](plates/one_box_mount_inner.svg)
14 | * [outer plate](plates/one_box_mount_outer.svg)
15 |
16 | | Item | Qty |
17 | | ------------------ | --- |
18 | | M4x14 | 8 |
19 | | M4 nut | 8 |
20 | | M4 (fender) washer | 8 |
21 | | #8-32 x 7/8" or 1" | 2 |
22 |
23 | In a pinch you can switch #8 to be M4... but either you have to get the length
24 | perfect or be at peace with the holes being re-threaded.
25 |
26 | ### Box
27 |
28 | This is built around a 188x193mm box that you can get
29 | [on Amazon](https://www.amazon.com/gp/product/B0725ZQFJW) or
30 | [Aliexpress](https://www.aliexpress.com/wholesale?SearchText=waterproof+192*188*100mm).
31 | There's plenty of room for activities in this.
32 |
33 | 
34 |
35 | You need to drill 4 holes in the back, and some holes in the sides. See the
36 | hole template for details (place it on the *back* of the box, and make sure it's
37 | in the correct orientation).
38 |
39 |
40 |
41 | * [hole template](plates/one_box_mount_hole_template.svg)
42 | * [lid hole template](plates/one_box_mount_lid_hole_template.svg)
43 | * [side hole template](plates/one_box_mount_front_hole_template.svg)
44 |
45 | ### 3D-printed shelf
46 |
47 |
48 |
49 | * [bracket+clip](shelf/bracket_both.stl)
50 | * [bracket](shelf/bracket_main.stl)
51 | * [clip](shelf/bracket_clip.stl)
52 |
53 | ### Power harness
54 |
55 | 
56 |
57 | | Item | Qty |
58 | | ------------- | --- |
59 | | EJ501A jack | 1 |
60 | | 24 AWG red stranded, 21cm long | 1 |
61 | | 24 AWG black stranded, 21cm long | 1 |
62 | | 18cm sleeving | 1 |
63 | | 25mm 1/4" heat shrink | 1 |
64 | | 25mm 3/16" heat shrink | 1 |
65 | | 12mm 1/8" heat shrink | 2 |
66 | | KK pin | 2 |
67 | | KK 2p housing | 1 |
68 |
69 | Note the center is typically positive (red).
70 |
71 | ### Button harness
72 |
73 | 
74 |
75 | | Item | Qty |
76 | | ------------- | --- |
77 | | Arcade button | 1 |
78 | | 24 AWG purple stranded, 20cm long | 1 |
79 | | 24 AWG black stranded, 20cm long | 1 |
80 | | 24 AWG yellow stranded, 21cm long | 1 |
81 | | 24 AWG gray stranded, 21cm long | 1 |
82 | | 12.5cm sleeving | 1 |
83 | | 25mm 3/16" heat shrink | 2 |
84 | | 12mm 3/16" heat shrink | 4 or 5 |
85 | | KK pin | 4 |
86 | | KK 5p housing | 1 |
87 |
88 | ### Epilog harness
89 |
90 | 
91 |
92 | | Item | Qty |
93 | | ------------- | --- |
94 | | 24 AWG black stranded, 80cm long | 1 |
95 | | 24 AWG black stranded, 82cm long | 1 |
96 | | 24 AWG green stranded, 3cm long | 1 |
97 | | SL female pin | 2 |
98 | | SL 2p female housing | 1 |
99 | | SL male pin | 2 |
100 | | SL 2p male housing | 1 |
101 | | KK pin | 2 |
102 | | KK 2p housing | 1 |
103 | | small ziptie | 1 |
104 |
105 | Note the KK housing is installed after routing through a hole at the bottom of
106 | the machine. When crimping the M-F on green, the pins should be 180 deg out of
107 | phase in order for the clips to line up like the photo.
108 |
109 | ### On BOFA
110 |
111 | If you're installing this above a BOFA filter, you should move the feet over to
112 | prevent slipping. 3 feet are easy, but the right front foot has a nut on the
113 | inside. Remove right panel to access.
114 |
115 | Once feet are removed, there are other holes about 4" closer to the middle that have
116 | the same thread.
117 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/button_harness.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/button_harness.jpg
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/epilog_harness.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/epilog_harness.jpg
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/Makefile:
--------------------------------------------------------------------------------
1 | OPENSCAD:=/usr/bin/openscad
2 |
3 | # Depends on both libs to be safe; this rebuilds more often than necessary
4 | # but this operation is quick.
5 | %.svg: %.scad one_box_mount_lib.scad two_box_mount_lib.scad
6 | "$(OPENSCAD)" -o "$@" "$<"
7 | sed -i.bak 's/svg width="\([^"]*\)" height="\([^"]*\)"/svg width="\1mm" height="\2mm"/' $@
8 |
9 | %.dxf: %.scad one_box_mount_lib.scad two_box_mount_lib.scad
10 | "$(OPENSCAD)" -o "$@" "$<"
11 |
12 | %_demo.png: %_demo.scad %_lib.scad
13 | "$(OPENSCAD)" -o "$@" --imgsize=2048,2048 --camera=0,-25,95,60,0,54,1300 "$<"
14 | convert "$@" -transparent '#ffffe5' -trim +repage "$@"
15 |
16 | .PHONY: all
17 | all: two_box_mount_inner.svg two_box_mount_outer.svg one_box_mount_inner.svg one_box_mount_outer.svg one_box_mount_hole_template.svg one_box_mount_lid_hole_template.svg one_box_mount_front_hole_template.svg one_box_mount_both.svg one_box_mount_both.dxf one_box_mount_demo.png two_box_mount_demo.png
18 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/README.md:
--------------------------------------------------------------------------------
1 | ## One-box version
2 |
3 | Very spacious, plenty of room to add an internal speaker.
4 |
5 | 
6 |
7 | | Item | Qty |
8 | | ---------- | --- |
9 | | M4x14 | 8 |
10 | | M4 nut | 8 |
11 | | M4 (fender) washer | 8 |
12 | | #8-32 x 7/8" or 1" | 2 |
13 |
14 | ## Two-box version
15 |
16 | This version allows you to put a Power Switch Tail in the rear box, while the
17 | front one houses the Pi, buttons, and badge reader.
18 |
19 | 
20 |
21 | | Item | Qty |
22 | | ---------- | --- |
23 | | M4x14 | 4 |
24 | | M4 nut | 4 |
25 | | M4 (fender) washer | 4 |
26 | | #8-32 x 7/8" or 1" | 2 |
27 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_both.scad:
--------------------------------------------------------------------------------
1 | include
2 |
3 | Inner();
4 | translate([plate_width*2+3,plate_height]) rotate([0,0,180]) Outer();
5 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/plates/one_box_mount_demo.png
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_demo.scad:
--------------------------------------------------------------------------------
1 | include
2 | rotate([90,0,0]) Exploded();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_front_hole_template.scad:
--------------------------------------------------------------------------------
1 | include
2 | FrontHoleTemplate();
3 | translate([120,0]) BackHoleTemplate();
4 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_hole_template.scad:
--------------------------------------------------------------------------------
1 | include
2 | HoleTemplate();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_inner.scad:
--------------------------------------------------------------------------------
1 | include
2 | Inner();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_lib.scad:
--------------------------------------------------------------------------------
1 | box_center = [120,160];
2 | box_size = [192,188];
3 | box_front_size = [100,188];
4 |
5 | // Non-square pattern intentional; avoid colliding with pi bracket and reduce
6 | // number of possible wrong orientations by half.
7 | box_hole_pattern = [
8 | [70, 60],
9 | [70, -60],
10 | [-70, 60],
11 | [-70, -60],
12 | ];
13 |
14 | box_hole_locations=[
15 | for (p = box_hole_pattern) box_center + p
16 | ];
17 |
18 | frame_hole_locations=[
19 | [20,7.5],
20 | [62,292.5],
21 | ];
22 |
23 | plate_width=235;
24 | plate_height=300;
25 |
26 | arcade_button_hole_size=24;
27 | arcade_button_pos = [18+27,15+42];
28 | badge_reader_hole_size=17;
29 |
30 | module Plate(cap_size) {
31 | difference() {
32 | square([plate_width, plate_height]);
33 | translate([0,plate_height-30]) rotate(atan2(30, 40)) square([100,100]);
34 | for(p = box_hole_locations)
35 | translate(p) circle(d=cap_size);
36 | for(p = frame_hole_locations)
37 | translate(p) circle(d=4.5);
38 | }
39 | }
40 |
41 | module Main() {
42 | Plate(cap_size=25,$fn=128);
43 | translate([plate_width+4,0])
44 | Plate(cap_size=4.2,$fn=128);
45 | }
46 |
47 | module CapHead(d,h) {
48 | color([0.8,0.5,0.5]) {
49 | translate([0,0,-h]) cylinder(d=d,h=h);
50 | cylinder(d=d*1.5,h=d);
51 | }
52 | }
53 |
54 | module Leader(h) {
55 | color([0.5,0.5,0.5,0.3]) cylinder(d=1,h=h);
56 | }
57 |
58 | module GhostBox(dims) {
59 | color([0.5,0.5,0.5,0.3]) cube(dims);
60 | }
61 |
62 | module Exploded() {
63 | linear_extrude(height=6) Inner();
64 | translate([0,0,80]) linear_extrude(height=6) Outer();
65 | for(p = box_hole_locations) {
66 | translate(p) {
67 | translate([0,0,-60]) scale([1,1,-1]) CapHead(4,20,$fn=32);
68 | translate([0,0,-40]) Leader(160);
69 | }
70 | }
71 | for(p = frame_hole_locations) {
72 | translate(p) {
73 | translate([0,0,130]) CapHead(4,20,$fn=32);
74 | translate([0,0,-20]) Leader(130);
75 | }
76 | }
77 | translate([box_center[0],box_center[1],120]) translate([-100,-100]) GhostBox([box_size[0],box_size[1],90]);
78 | }
79 |
80 | module Slot(d, dist) {
81 | hull() for(y=[dist/2,-dist/2]) translate([0,y]) circle(d=d);
82 | }
83 |
84 | module ZiptieMount() {
85 | for(x=[200,210]) translate([x,30]) Slot(3, 7, $fn=16);
86 | }
87 |
88 | module Inner() {
89 | difference() {
90 | Plate(cap_size=25,$fn=128);
91 | hull() ZiptieMount();
92 | }
93 | }
94 |
95 | module Outer() {
96 | difference() {
97 | Plate(cap_size=4.2,$fn=128);
98 | ZiptieMount();
99 | }
100 | }
101 |
102 | module HoleTemplate() {
103 | $fn=32;
104 | difference() {
105 | square(box_size, center=true);
106 | for(p = box_hole_pattern) {
107 | translate(p) circle(d=3);
108 | }
109 | translate([-90,0]) text("A", halign="left", size=5);
110 | translate([90,0]) text("B", halign="right", size=5);
111 | translate([0,60]) text("4x 4.2mm", halign="center", size=5);
112 | translate([80,40]) text("Front ->", halign="right", size=5);
113 | translate([-80,40]) text("<- Back", halign="left", size=5);
114 | translate([0,10]) text("(place on back of box)", halign="center", size=8);
115 | translate([0,-10]) text("(verify interior 5 holes at sides)", halign="center", size=8);
116 | }
117 | }
118 |
119 | module CrosshairCircle(d) {
120 | difference() {
121 | circle(d=d);
122 | square([1,d*0.7], center=true);
123 | square([d*0.7, 1], center=true);
124 | }
125 | }
126 |
127 | module LidHoleTemplate() {
128 | $fn=32;
129 | difference() {
130 | square(box_size, center=true);
131 | translate([-box_size[0]/2+3,0]) text("C", halign="left", size=5);
132 | translate([box_size[0]/2-3,0]) text("D", halign="right", size=5);
133 | for(y_scale=[1,-1])
134 | scale([1,y_scale])
135 | translate([-box_size[0]/2+arcade_button_pos[0],
136 | -box_size[1]/2+arcade_button_pos[1]])
137 | CrosshairCircle(arcade_button_hole_size);
138 | }
139 | }
140 |
141 | module FrontHoleTemplate() {
142 | $fn=32;
143 | difference() {
144 | square(box_front_size, center=true);
145 | translate([box_front_size[0]/2-20, 0]) square([1,box_front_size[1]-2], center=true);
146 | text("Front", halign="center", size=5);
147 | translate([-box_front_size[0]/2+3,0]) text("B", halign="left", size=5);
148 | translate([box_front_size[0]/2-3,0]) text("C", halign="right", size=5);
149 | translate([0,60]) CrosshairCircle(badge_reader_hole_size);
150 | }
151 | }
152 |
153 | module BackHoleTemplate() {
154 | $fn=32;
155 | difference() {
156 | square(box_front_size, center=true);
157 | translate([-box_front_size[0]/2+20, 0]) square([1,box_front_size[1]-2], center=true);
158 | text("Back", halign="center", size=5);
159 | translate([box_front_size[0]/2-3,0]) text("A", halign="right", size=5);
160 | translate([-box_front_size[0]/2+3,0]) text("D", halign="left", size=5);
161 | translate([box_front_size[0]/2-35,box_front_size[1]/2-35])
162 | CrosshairCircle(8); // power
163 | translate([box_front_size[0]/2-50,box_front_size[1]/2-35])
164 | CrosshairCircle(8); // actuator cables
165 | translate([box_front_size[0]/2-80+4,box_front_size[1]/2-35])
166 | CrosshairCircle(8); // actuator cables
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_lid_hole_template.scad:
--------------------------------------------------------------------------------
1 | include
2 | LidHoleTemplate();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_lid_hole_template.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
50 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/one_box_mount_outer.scad:
--------------------------------------------------------------------------------
1 | include
2 | Outer();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/plates/screenshot.png
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/two_box_mount.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/plates/two_box_mount.png
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/two_box_mount_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/plates/two_box_mount_demo.png
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/two_box_mount_demo.scad:
--------------------------------------------------------------------------------
1 | include
2 | rotate([90,0,0]) Exploded();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/two_box_mount_inner.scad:
--------------------------------------------------------------------------------
1 | include
2 | Inner();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/two_box_mount_lib.scad:
--------------------------------------------------------------------------------
1 | box_hole_locations=[
2 | [30,107],
3 | [80,107],
4 | [130,107],
5 | [217,107],
6 |
7 | [30,255],
8 | [80,255],
9 | [130,294],
10 | [217,294],
11 | ];
12 |
13 | frame_hole_locations=[
14 | [20,20],
15 | [62,305],
16 | ];
17 |
18 | plate_width=235;
19 | plate_height=325;
20 |
21 | module Plate(cap_size) {
22 | difference() {
23 | square([plate_width, plate_height]);
24 | translate([0,plate_height-30]) rotate(atan2(30, 40)) square([100,100]);
25 | for(p = box_hole_locations)
26 | translate(p) circle(d=cap_size);
27 | for(p = frame_hole_locations)
28 | translate(p) circle(d=4.5);
29 | }
30 | }
31 |
32 | module Main() {
33 | Plate(cap_size=25,$fn=128);
34 | translate([plate_width+4,0])
35 | Plate(cap_size=4.2,$fn=128);
36 | }
37 |
38 | module CapHead(d,h) {
39 | color([0.8,0.5,0.5]) {
40 | translate([0,0,-h]) cylinder(d=d,h=h);
41 | cylinder(d=d*1.5,h=d);
42 | }
43 | }
44 |
45 | module Leader(h) {
46 | color([0.5,0.5,0.5,0.3]) cylinder(d=1,h=h);
47 | }
48 |
49 | module GhostBox(dims) {
50 | color([0.5,0.5,0.5,0.3]) cube(dims);
51 | }
52 |
53 | module Exploded() {
54 | linear_extrude(height=6) Inner();
55 | translate([0,0,80]) linear_extrude(height=6) Outer();
56 | for(p = box_hole_locations) {
57 | translate(p) {
58 | translate([0,0,-60]) scale([1,1,-1]) CapHead(4,20,$fn=32);
59 | translate([0,0,-40]) Leader(160);
60 | }
61 | }
62 | for(p = frame_hole_locations) {
63 | translate(p) {
64 | translate([0,0,130]) CapHead(4,20,$fn=32);
65 | translate([0,0,-20]) Leader(130);
66 | }
67 | }
68 | translate([20,80,120]) GhostBox([70,180,50]);
69 | translate([115,90,120]) GhostBox([100,200,50]);
70 | }
71 |
72 | module Inner() {
73 | Plate(cap_size=25,$fn=128);
74 | }
75 |
76 | module Outer() {
77 | Plate(cap_size=4.2,$fn=128);
78 | }
79 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/plates/two_box_mount_outer.scad:
--------------------------------------------------------------------------------
1 | include
2 | Outer();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/power_harness.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/power_harness.jpg
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/shelf/Makefile:
--------------------------------------------------------------------------------
1 | OPENSCAD:=/usr/bin/openscad
2 |
3 | # TODO: convert to binary for smaller size
4 | %.stl: %.scad bracket_lib.scad
5 | "$(OPENSCAD)" -o "$@" "$<"
6 |
7 | %.png: %.scad bracket_lib.scad
8 | "$(OPENSCAD)" -o "$@" --imgsize=2048,2048 --camera=-16,-32,18,62,0,45,325 "$<"
9 | convert "$@" -transparent '#ffffe5' -trim +repage "$@"
10 |
11 | .PHONY: all
12 | all: bracket_both.stl bracket_both.png bracket_main.stl bracket_clip.stl
13 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/shelf/bracket_both.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/shelf/bracket_both.png
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/shelf/bracket_both.scad:
--------------------------------------------------------------------------------
1 | include
2 | Main(hard_support=false);
3 | MainClip();
4 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/shelf/bracket_clip.scad:
--------------------------------------------------------------------------------
1 | include
2 | Clip();
3 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/shelf/bracket_in_box.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/docs/tool-connection/epilog_mini_24/shelf/bracket_in_box.jpg
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/shelf/bracket_lib.scad:
--------------------------------------------------------------------------------
1 | Thickness = 5;
2 | BaseHeight = 11;
3 | Height = 58;
4 | ToAngle = 18;
5 | AngleHeight = 2;
6 | AfterAngle = 3;
7 | InnerRadius = 0.5;
8 |
9 | HolePositions = [
10 | [3,-10],
11 | [3,-35],
12 | [3,-75],
13 | ];
14 |
15 | module SideProfile() {
16 | difference() {
17 | union() {
18 | translate([-Thickness,0]) square([Thickness+1, BaseHeight+Height]);
19 | translate([-0.01,0]) square([ToAngle+AngleHeight+AfterAngle, BaseHeight+AngleHeight]);
20 | }
21 | hull() {
22 | for(yo=[InnerRadius, InnerRadius+Height])
23 | translate([InnerRadius, BaseHeight+yo]) circle(r=InnerRadius, $fn=32);
24 | translate([ToAngle-1,BaseHeight]) square([1,1]);
25 | translate([ToAngle+AngleHeight-1, BaseHeight+AngleHeight]) square([1,1]);
26 | }
27 | }
28 | }
29 |
30 | module CountersunkHole() {
31 | // bottom
32 | difference() {
33 | translate([0,0,-1]) cylinder(d=8,h=7.4,$fn=128);
34 | translate([3,0,5+6]) cube([3,10,10], center=true);
35 | translate([-3,0,5+6]) cube([3,10,10], center=true);
36 | }
37 | // middle
38 | cylinder(d=3,h=100,$fn=32);
39 | // top
40 | translate([0,0,BaseHeight-3]) cylinder(d=6,h=10,$fn=128);
41 | }
42 |
43 | module CountersunkHoles() {
44 | for(p=HolePositions) {
45 | translate(p) CountersunkHole();
46 | }
47 | }
48 |
49 | module Tab() {
50 | rotate([90,0,0]) linear_extrude(height=4.5) polygon(points=[[0,0], [10,0], [10,5], [5,5]]);
51 | }
52 |
53 | module NegativeFillet(r) {
54 | linear_extrude(height=100,convexity=4)
55 | difference() {
56 | translate([-1,-1]) square([r+1,r+1]);
57 | translate([r,r]) circle(r=r,$fn=32);
58 | }
59 | }
60 |
61 | module Clip() {
62 | difference() {
63 | linear_extrude(height=6) offset(r=1,$fn=32) offset(delta=-1) square([13,7.5]);
64 | hull() {
65 | translate([-3.8,-0.25,3]) cube([13,10,6]);
66 | translate([-0.8,-0.25,6.01]) cube([13,10,6]);
67 | }
68 | translate([3,7.5/2,-1]) cylinder(d=3.2,h=10,$fn=32);
69 | translate([3,7.5/2,-2]) cylinder(d=6.2,h=3,$fn=32);
70 | }
71 | }
72 |
73 | module Main() {
74 | difference() {
75 | rotate([90,0,0]) linear_extrude(height=86, convexity=4) SideProfile();
76 | CountersunkHoles();
77 | translate([-Thickness/2,-61,BaseHeight+Height-12]) cylinder(d=2.7,h=13,$fn=32);
78 | // Base fillets
79 | translate([ToAngle+AngleHeight+AfterAngle,-86,-1]) rotate([0,0,90]) NegativeFillet(2);
80 | translate([ToAngle+AngleHeight+AfterAngle,0,-1]) rotate([0,0,180]) NegativeFillet(2);
81 | // Top fillets
82 | translate([-50,-86,BaseHeight+Height]) rotate([0,90,0]) NegativeFillet(2);
83 | translate([-50,0,BaseHeight+Height]) rotate([-90,0,0]) rotate([0,90,0]) NegativeFillet(2);
84 | }
85 | translate([5,0,BaseHeight-0.01]) Tab();
86 | translate([5,-61.5,BaseHeight-0.01]) Tab();
87 | }
88 |
89 | module MainClip() {
90 | translate([0,-95,0]) Clip();
91 | }
92 |
--------------------------------------------------------------------------------
/docs/tool-connection/epilog_mini_24/shelf/bracket_main.scad:
--------------------------------------------------------------------------------
1 | include
2 | Main();
3 |
--------------------------------------------------------------------------------
/hardware/README.md:
--------------------------------------------------------------------------------
1 | The job of the hardware board is adapt a commodity board to customizable buttons
2 | and actuators. Currently there is only one board:
3 |
4 | ## Pi Hat 1
5 | 
6 |
7 | A custom Pi hat which is pretty simple to build (we held intro soldering classes
8 | around it). The board takes 12V in, powers the Pi under it, and switches 12V
9 | for lights on buttons (up to six of them), a high-current output for external
10 | relays, and two small relays intended for volt-free switching.
11 |
--------------------------------------------------------------------------------
/hardware/box.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/box.jpg
--------------------------------------------------------------------------------
/hardware/pi-bracket-1/README.md:
--------------------------------------------------------------------------------
1 | This holder fits the hole pattern found on a common unbranded 190x185x100mm box, such as https://www.amazon.com/dp/B00UBX0XH6
2 |
3 | 
4 |
5 | Source at
6 | https://cad.onshape.com/documents/05d5fe3c5ee63c03d087e8e2/w/24837917d2c22fd129fda85b/e/478f29442292e5ba2817433a (version V1)
7 |
8 | Assembly requires:
9 |
10 | 3x or 4x KA30x8 screws (#4x1/4" is close, but beware of stripping the threads)
11 | 1x M2.5x11 threaded standoff
12 | 2x M2.5x6 machine screws
13 |
14 | We typically print the bracket on its largest flat face.
--------------------------------------------------------------------------------
/hardware/pi-bracket-1/pibracket.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-bracket-1/pibracket.jpg
--------------------------------------------------------------------------------
/hardware/pi-bracket-1/pibracket.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-bracket-1/pibracket.stl
--------------------------------------------------------------------------------
/hardware/pi-bracket-1/piclip.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-bracket-1/piclip.stl
--------------------------------------------------------------------------------
/hardware/pi-hat-1/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: zip
2 | zip:
3 | zip -o ph1.zip ms_auth_breakout.{GKO,GTL,GBL,GTO,GTP,GTS,GBO,GBS}
4 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/README.md:
--------------------------------------------------------------------------------
1 | # Pi Hat 1
2 |
3 | This is an example board that fits a Raspberry Pi. We tried to make it fun
4 | enough to assemble as a beginning soldering exercise (yes, even with surface
5 | mount!), and not use anything too strange.
6 |
7 | 
8 |
9 | ## Part notes
10 |
11 | The odd board shape is to preserve easy access to CSI bus in case you're using
12 | a camera.
13 |
14 | We tested with 2x20 headers both cheap (eBay) and expensive
15 | (SFH11-PBPC-D20-ST-BK at $1.97). All fit, barely clearing the holes.
16 |
17 | The top hole is intended as mechanical joining, but as in all Pi hats, needs an
18 | odd size standoff (M2.5 x 11mm).
19 |
20 | You don't need both the 2-pin and barrel supply (in fact, don't power both
21 | simultaneously), but having the second set of pads makes probing easier.
22 |
23 | The resistor network can be bussed or independent, either will work. 10k
24 | appears sufficient to overpower the onboard pulldown on boot, but 4.7k (less
25 | common) works too.
26 |
27 |
28 | ## Pinouts
29 |
30 | The button pinout is (left-to-right with the tab facing down) is (``IN, n/c,
31 | GND, +12V, Switched GND``). It's intended for a light and/or button per
32 | connector. Arcade buttons work fairly well if your enclosure is big enough.
33 |
34 | 
35 |
36 | The only connector with a freewheeling diode is the 3-pin one marked high current. It's intended for relay or solenoid use, like for a door. It's fairly easy to blow the driver chip on all the others.
37 |
38 | You can crimp or solder the switch and light side; you should crimp the Molex KK side.
39 |
40 |
41 | ## The 30-second guide to crimping Molex KK
42 |
43 | The best tool is Molex 63811-8200, but it's very expensive (350 USD). We used a budget crimper SN-2549 (23 USD) for these photos, which is the cheapest we've tried that does OK.
44 |
45 | For a walkthrough of this process, University of Manchester has produced a video which details the workflow: [https://www.youtube.com/watch?v=8jcfD1UW8SE](https://www.youtube.com/watch?v=8jcfD1UW8SE)
46 |
47 | 
48 | 1. Strip 3mm of wire.
49 |
50 | 
51 | 2. Insert into crimper with the open end facing you.
52 |
53 | 
54 | 3. Don't crush the spring, which is on the back side, while you close a couple of clicks. Now insert wire from the front and complete the cycle.
55 |
56 | 
57 | 4. This is acceptably crimped. It's not ideal, but acceptable.
58 |
59 | 
60 | 5. Insert into housing with tiny tooth up, and the spring down in this orientation. It should lock.
61 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/board.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/board.png
--------------------------------------------------------------------------------
/hardware/pi-hat-1/buttonwiring.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/buttonwiring.jpg
--------------------------------------------------------------------------------
/hardware/pi-hat-1/crimping1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/crimping1.jpg
--------------------------------------------------------------------------------
/hardware/pi-hat-1/crimping2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/crimping2.jpg
--------------------------------------------------------------------------------
/hardware/pi-hat-1/crimping3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/crimping3.jpg
--------------------------------------------------------------------------------
/hardware/pi-hat-1/crimping4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/crimping4.jpg
--------------------------------------------------------------------------------
/hardware/pi-hat-1/crimping5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/crimping5.jpg
--------------------------------------------------------------------------------
/hardware/pi-hat-1/fp-info-cache:
--------------------------------------------------------------------------------
1 | 0
2 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/fp-lib-table:
--------------------------------------------------------------------------------
1 | (fp_lib_table
2 | (lib (name ms_auth_breakout)(type KiCad)(uri "$(KIPRJMOD)/ms_auth_breakout.pretty")(options "")(descr ""))
3 | )
4 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-B_Adhes.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Glue,Bot*%
6 | %TF.FilePolarity,Positive*%
7 | %FSLAX46Y46*%
8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
9 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
10 | %MOMM*%
11 | %LPD*%
12 | G04 APERTURE LIST*
13 | %ADD10C,0.050000*%
14 | %ADD11C,0.100000*%
15 | G04 APERTURE END LIST*
16 | D10*
17 | X119557800Y-133896100D02*
18 | G75*
19 | G02X115747800Y-130086100I0J3810000D01*
20 | G01*
21 | X119557800Y-133896100D02*
22 | X177342800Y-133896100D01*
23 | X181254400Y-130086100D02*
24 | G75*
25 | G02X177342800Y-133896100I-3860800J50800D01*
26 | G01*
27 | X181254400Y-130086100D02*
28 | X181254400Y-79921100D01*
29 | X177342800Y-76111100D02*
30 | G75*
31 | G02X181254400Y-79921100I50800J-3860800D01*
32 | G01*
33 | X177342800Y-76111100D02*
34 | X140512800Y-76111100D01*
35 | X137972800Y-78651100D02*
36 | G75*
37 | G02X140512800Y-76111100I2540000J0D01*
38 | G01*
39 | X137972800Y-78651100D02*
40 | X137972800Y-100241100D01*
41 | X135432800Y-102781100D02*
42 | G75*
43 | G03X137972800Y-100241100I0J2540000D01*
44 | G01*
45 | X135432800Y-102781100D02*
46 | X118287800Y-102781100D01*
47 | X115747800Y-105321100D02*
48 | G75*
49 | G02X118287800Y-102781100I2540000J0D01*
50 | G01*
51 | X115747800Y-105321100D02*
52 | X115747800Y-130086100D01*
53 | D11*
54 | G36*
55 | X152977900Y-80356200D02*
56 | G01*
57 | X152977900Y-80756000D01*
58 | X152177700Y-80756000D01*
59 | X152177700Y-80356200D01*
60 | X152977900Y-80356200D01*
61 | G37*
62 | G36*
63 | X134345400Y-122901200D02*
64 | G01*
65 | X134345400Y-123301000D01*
66 | X133345200Y-123301000D01*
67 | X133345200Y-122901200D01*
68 | X134345400Y-122901200D01*
69 | G37*
70 | G36*
71 | X137520400Y-122901200D02*
72 | G01*
73 | X137520400Y-123301000D01*
74 | X136520200Y-123301000D01*
75 | X136520200Y-122901200D01*
76 | X137520400Y-122901200D01*
77 | G37*
78 | G36*
79 | X143870400Y-122901200D02*
80 | G01*
81 | X143870400Y-123301000D01*
82 | X142870200Y-123301000D01*
83 | X142870200Y-122901200D01*
84 | X143870400Y-122901200D01*
85 | G37*
86 | G36*
87 | X140695400Y-122901200D02*
88 | G01*
89 | X140695400Y-123301000D01*
90 | X139695200Y-123301000D01*
91 | X139695200Y-122901200D01*
92 | X140695400Y-122901200D01*
93 | G37*
94 | M02*
95 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-B_CrtYd.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Other,User*%
6 | %FSLAX46Y46*%
7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
8 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
9 | %MOMM*%
10 | %LPD*%
11 | G04 APERTURE LIST*
12 | %ADD10C,0.050000*%
13 | G04 APERTURE END LIST*
14 | D10*
15 | X119557800Y-133896100D02*
16 | G75*
17 | G02X115747800Y-130086100I0J3810000D01*
18 | G01*
19 | X119557800Y-133896100D02*
20 | X177342800Y-133896100D01*
21 | X181254400Y-130086100D02*
22 | G75*
23 | G02X177342800Y-133896100I-3860800J50800D01*
24 | G01*
25 | X181254400Y-130086100D02*
26 | X181254400Y-79921100D01*
27 | X177342800Y-76111100D02*
28 | G75*
29 | G02X181254400Y-79921100I50800J-3860800D01*
30 | G01*
31 | X177342800Y-76111100D02*
32 | X140512800Y-76111100D01*
33 | X137972800Y-78651100D02*
34 | G75*
35 | G02X140512800Y-76111100I2540000J0D01*
36 | G01*
37 | X137972800Y-78651100D02*
38 | X137972800Y-100241100D01*
39 | X135432800Y-102781100D02*
40 | G75*
41 | G03X137972800Y-100241100I0J2540000D01*
42 | G01*
43 | X135432800Y-102781100D02*
44 | X118287800Y-102781100D01*
45 | X115747800Y-105321100D02*
46 | G75*
47 | G02X118287800Y-102781100I2540000J0D01*
48 | G01*
49 | X115747800Y-105321100D02*
50 | X115747800Y-130086100D01*
51 | M02*
52 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-B_Paste.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Paste,Bot*%
6 | %TF.FilePolarity,Positive*%
7 | %FSLAX46Y46*%
8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
9 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
10 | %MOMM*%
11 | %LPD*%
12 | G04 APERTURE LIST*
13 | %ADD10C,0.050000*%
14 | %ADD11R,0.660400X2.032000*%
15 | %ADD12R,1.800000X1.600000*%
16 | %ADD13R,0.800000X0.900000*%
17 | %ADD14R,0.900000X0.800000*%
18 | %ADD15R,2.400000X1.800000*%
19 | %ADD16R,1.500000X1.300000*%
20 | G04 APERTURE END LIST*
21 | D10*
22 | X119557800Y-133896100D02*
23 | G75*
24 | G02X115747800Y-130086100I0J3810000D01*
25 | G01*
26 | X119557800Y-133896100D02*
27 | X177342800Y-133896100D01*
28 | X181254400Y-130086100D02*
29 | G75*
30 | G02X177342800Y-133896100I-3860800J50800D01*
31 | G01*
32 | X181254400Y-130086100D02*
33 | X181254400Y-79921100D01*
34 | X177342800Y-76111100D02*
35 | G75*
36 | G02X181254400Y-79921100I50800J-3860800D01*
37 | G01*
38 | X177342800Y-76111100D02*
39 | X140512800Y-76111100D01*
40 | X137972800Y-78651100D02*
41 | G75*
42 | G02X140512800Y-76111100I2540000J0D01*
43 | G01*
44 | X137972800Y-78651100D02*
45 | X137972800Y-100241100D01*
46 | X135432800Y-102781100D02*
47 | G75*
48 | G03X137972800Y-100241100I0J2540000D01*
49 | G01*
50 | X135432800Y-102781100D02*
51 | X118287800Y-102781100D01*
52 | X115747800Y-105321100D02*
53 | G75*
54 | G02X118287800Y-102781100I2540000J0D01*
55 | G01*
56 | X115747800Y-105321100D02*
57 | X115747800Y-130086100D01*
58 | D11*
59 | X119557800Y-112407700D03*
60 | X119557800Y-118554500D03*
61 | X120827800Y-112407700D03*
62 | X122097800Y-112407700D03*
63 | X120827800Y-118554500D03*
64 | X122097800Y-118554500D03*
65 | X123367800Y-112407700D03*
66 | X123367800Y-118554500D03*
67 | X124637800Y-112407700D03*
68 | X124637800Y-118554500D03*
69 | X125907800Y-112407700D03*
70 | X127177800Y-112407700D03*
71 | X125907800Y-118554500D03*
72 | X127177800Y-118554500D03*
73 | X128447800Y-112407700D03*
74 | X128447800Y-118554500D03*
75 | D12*
76 | X152577800Y-81956100D03*
77 | X152577800Y-79156100D03*
78 | D13*
79 | X140512800Y-82631100D03*
80 | X139562800Y-84731100D03*
81 | X141462800Y-84731100D03*
82 | X143687800Y-82631100D03*
83 | X142737800Y-84731100D03*
84 | X144637800Y-84731100D03*
85 | X146862800Y-82631100D03*
86 | X145912800Y-84731100D03*
87 | X147812800Y-84731100D03*
88 | D14*
89 | X120997800Y-105321100D03*
90 | X123097800Y-106271100D03*
91 | X123097800Y-104371100D03*
92 | X160367800Y-92621100D03*
93 | X162467800Y-93571100D03*
94 | X162467800Y-91671100D03*
95 | X160367800Y-97701100D03*
96 | X162467800Y-98651100D03*
97 | X162467800Y-96751100D03*
98 | D15*
99 | X152577800Y-100361100D03*
100 | X152577800Y-96311100D03*
101 | X152577800Y-91471100D03*
102 | X152577800Y-87421100D03*
103 | X118287800Y-105836100D03*
104 | X118287800Y-109886100D03*
105 | D16*
106 | X133845300Y-124051100D03*
107 | X133845300Y-122151100D03*
108 | X137020300Y-124051100D03*
109 | X137020300Y-122151100D03*
110 | X143370300Y-124051100D03*
111 | X143370300Y-122151100D03*
112 | X140195300Y-124051100D03*
113 | X140195300Y-122151100D03*
114 | M02*
115 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-Cmts_User.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Other,Comment*%
6 | %FSLAX46Y46*%
7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
8 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
9 | %MOMM*%
10 | %LPD*%
11 | G04 APERTURE LIST*
12 | %ADD10C,0.050000*%
13 | G04 APERTURE END LIST*
14 | D10*
15 | X119557800Y-133896100D02*
16 | G75*
17 | G02X115747800Y-130086100I0J3810000D01*
18 | G01*
19 | X119557800Y-133896100D02*
20 | X177342800Y-133896100D01*
21 | X181254400Y-130086100D02*
22 | G75*
23 | G02X177342800Y-133896100I-3860800J50800D01*
24 | G01*
25 | X181254400Y-130086100D02*
26 | X181254400Y-79921100D01*
27 | X177342800Y-76111100D02*
28 | G75*
29 | G02X181254400Y-79921100I50800J-3860800D01*
30 | G01*
31 | X177342800Y-76111100D02*
32 | X140512800Y-76111100D01*
33 | X137972800Y-78651100D02*
34 | G75*
35 | G02X140512800Y-76111100I2540000J0D01*
36 | G01*
37 | X137972800Y-78651100D02*
38 | X137972800Y-100241100D01*
39 | X135432800Y-102781100D02*
40 | G75*
41 | G03X137972800Y-100241100I0J2540000D01*
42 | G01*
43 | X135432800Y-102781100D02*
44 | X118287800Y-102781100D01*
45 | X115747800Y-105321100D02*
46 | G75*
47 | G02X118287800Y-102781100I2540000J0D01*
48 | G01*
49 | X115747800Y-105321100D02*
50 | X115747800Y-130086100D01*
51 | M02*
52 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-Dwgs_User.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,OtherDrawing,Comment*%
6 | %FSLAX46Y46*%
7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
8 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
9 | %MOMM*%
10 | %LPD*%
11 | G04 APERTURE LIST*
12 | %ADD10C,0.050000*%
13 | %ADD11C,0.050800*%
14 | %ADD12C,0.127000*%
15 | G04 APERTURE END LIST*
16 | D10*
17 | X119557800Y-133896100D02*
18 | G75*
19 | G02X115747800Y-130086100I0J3810000D01*
20 | G01*
21 | X119557800Y-133896100D02*
22 | X177342800Y-133896100D01*
23 | X181254400Y-130086100D02*
24 | G75*
25 | G02X177342800Y-133896100I-3860800J50800D01*
26 | G01*
27 | X181254400Y-130086100D02*
28 | X181254400Y-79921100D01*
29 | X177342800Y-76111100D02*
30 | G75*
31 | G02X181254400Y-79921100I50800J-3860800D01*
32 | G01*
33 | X177342800Y-76111100D02*
34 | X140512800Y-76111100D01*
35 | X137972800Y-78651100D02*
36 | G75*
37 | G02X140512800Y-76111100I2540000J0D01*
38 | G01*
39 | X137972800Y-78651100D02*
40 | X137972800Y-100241100D01*
41 | X135432800Y-102781100D02*
42 | G75*
43 | G03X137972800Y-100241100I0J2540000D01*
44 | G01*
45 | X135432800Y-102781100D02*
46 | X118287800Y-102781100D01*
47 | X115747800Y-105321100D02*
48 | G75*
49 | G02X118287800Y-102781100I2540000J0D01*
50 | G01*
51 | X115747800Y-105321100D02*
52 | X115747800Y-130086100D01*
53 | D11*
54 | X170803550Y-121286850D02*
55 | X172452050Y-121286850D01*
56 | X170803550Y-124915350D02*
57 | X170803550Y-121286850D01*
58 | X172452050Y-124915350D02*
59 | X170803550Y-124915350D01*
60 | X172452050Y-121286850D02*
61 | X172452050Y-124915350D01*
62 | X168263550Y-77471850D02*
63 | X169912050Y-77471850D01*
64 | X168263550Y-81100350D02*
65 | X168263550Y-77471850D01*
66 | X169912050Y-81100350D02*
67 | X168263550Y-81100350D01*
68 | X169912050Y-77471850D02*
69 | X169912050Y-81100350D01*
70 | X151594800Y-83029100D02*
71 | X153560800Y-83029100D01*
72 | X153560800Y-78083100D02*
73 | X151594800Y-78083100D01*
74 | X153560800Y-83029100D02*
75 | X153560800Y-78083100D01*
76 | X151594800Y-78083100D02*
77 | X151594800Y-83029100D01*
78 | D12*
79 | X165912800Y-104051100D02*
80 | X176072800Y-104051100D01*
81 | X165912800Y-93891100D02*
82 | X165912800Y-104051100D01*
83 | X176072800Y-93891100D02*
84 | X165912800Y-93891100D01*
85 | X176072800Y-104051100D02*
86 | X176072800Y-93891100D01*
87 | D11*
88 | X134669550Y-121286850D02*
89 | X133021050Y-121286850D01*
90 | X134669550Y-124915350D02*
91 | X134669550Y-121286850D01*
92 | X133021050Y-124915350D02*
93 | X134669550Y-124915350D01*
94 | X133021050Y-121286850D02*
95 | X133021050Y-124915350D01*
96 | X137844550Y-121286850D02*
97 | X136196050Y-121286850D01*
98 | X137844550Y-124915350D02*
99 | X137844550Y-121286850D01*
100 | X136196050Y-124915350D02*
101 | X137844550Y-124915350D01*
102 | X136196050Y-121286850D02*
103 | X136196050Y-124915350D01*
104 | X144194550Y-121286850D02*
105 | X142546050Y-121286850D01*
106 | X144194550Y-124915350D02*
107 | X144194550Y-121286850D01*
108 | X142546050Y-124915350D02*
109 | X144194550Y-124915350D01*
110 | X142546050Y-121286850D02*
111 | X142546050Y-124915350D01*
112 | X141019550Y-121286850D02*
113 | X139371050Y-121286850D01*
114 | X141019550Y-124915350D02*
115 | X141019550Y-121286850D01*
116 | X139371050Y-124915350D02*
117 | X141019550Y-124915350D01*
118 | X139371050Y-121286850D02*
119 | X139371050Y-124915350D01*
120 | M02*
121 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-Eco1_User.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Other,ECO1*%
6 | %FSLAX46Y46*%
7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
8 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
9 | %MOMM*%
10 | %LPD*%
11 | G04 APERTURE LIST*
12 | %ADD10C,0.050000*%
13 | G04 APERTURE END LIST*
14 | D10*
15 | X119557800Y-133896100D02*
16 | G75*
17 | G02X115747800Y-130086100I0J3810000D01*
18 | G01*
19 | X119557800Y-133896100D02*
20 | X177342800Y-133896100D01*
21 | X181254400Y-130086100D02*
22 | G75*
23 | G02X177342800Y-133896100I-3860800J50800D01*
24 | G01*
25 | X181254400Y-130086100D02*
26 | X181254400Y-79921100D01*
27 | X177342800Y-76111100D02*
28 | G75*
29 | G02X181254400Y-79921100I50800J-3860800D01*
30 | G01*
31 | X177342800Y-76111100D02*
32 | X140512800Y-76111100D01*
33 | X137972800Y-78651100D02*
34 | G75*
35 | G02X140512800Y-76111100I2540000J0D01*
36 | G01*
37 | X137972800Y-78651100D02*
38 | X137972800Y-100241100D01*
39 | X135432800Y-102781100D02*
40 | G75*
41 | G03X137972800Y-100241100I0J2540000D01*
42 | G01*
43 | X135432800Y-102781100D02*
44 | X118287800Y-102781100D01*
45 | X115747800Y-105321100D02*
46 | G75*
47 | G02X118287800Y-102781100I2540000J0D01*
48 | G01*
49 | X115747800Y-105321100D02*
50 | X115747800Y-130086100D01*
51 | M02*
52 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-Eco2_User.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Other,ECO2*%
6 | %FSLAX46Y46*%
7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
8 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
9 | %MOMM*%
10 | %LPD*%
11 | G04 APERTURE LIST*
12 | %ADD10C,0.050000*%
13 | G04 APERTURE END LIST*
14 | D10*
15 | X119557800Y-133896100D02*
16 | G75*
17 | G02X115747800Y-130086100I0J3810000D01*
18 | G01*
19 | X119557800Y-133896100D02*
20 | X177342800Y-133896100D01*
21 | X181254400Y-130086100D02*
22 | G75*
23 | G02X177342800Y-133896100I-3860800J50800D01*
24 | G01*
25 | X181254400Y-130086100D02*
26 | X181254400Y-79921100D01*
27 | X177342800Y-76111100D02*
28 | G75*
29 | G02X181254400Y-79921100I50800J-3860800D01*
30 | G01*
31 | X177342800Y-76111100D02*
32 | X140512800Y-76111100D01*
33 | X137972800Y-78651100D02*
34 | G75*
35 | G02X140512800Y-76111100I2540000J0D01*
36 | G01*
37 | X137972800Y-78651100D02*
38 | X137972800Y-100241100D01*
39 | X135432800Y-102781100D02*
40 | G75*
41 | G03X137972800Y-100241100I0J2540000D01*
42 | G01*
43 | X135432800Y-102781100D02*
44 | X118287800Y-102781100D01*
45 | X115747800Y-105321100D02*
46 | G75*
47 | G02X118287800Y-102781100I2540000J0D01*
48 | G01*
49 | X115747800Y-105321100D02*
50 | X115747800Y-130086100D01*
51 | M02*
52 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-Edge_Cuts.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Profile,NP*%
6 | %FSLAX46Y46*%
7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
8 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
9 | %MOMM*%
10 | %LPD*%
11 | G04 APERTURE LIST*
12 | %ADD10C,0.050000*%
13 | G04 APERTURE END LIST*
14 | D10*
15 | X119557800Y-133896100D02*
16 | G75*
17 | G02X115747800Y-130086100I0J3810000D01*
18 | G01*
19 | X119557800Y-133896100D02*
20 | X177342800Y-133896100D01*
21 | X181254400Y-130086100D02*
22 | G75*
23 | G02X177342800Y-133896100I-3860800J50800D01*
24 | G01*
25 | X181254400Y-130086100D02*
26 | X181254400Y-79921100D01*
27 | X177342800Y-76111100D02*
28 | G75*
29 | G02X181254400Y-79921100I50800J-3860800D01*
30 | G01*
31 | X177342800Y-76111100D02*
32 | X140512800Y-76111100D01*
33 | X137972800Y-78651100D02*
34 | G75*
35 | G02X140512800Y-76111100I2540000J0D01*
36 | G01*
37 | X137972800Y-78651100D02*
38 | X137972800Y-100241100D01*
39 | X135432800Y-102781100D02*
40 | G75*
41 | G03X137972800Y-100241100I0J2540000D01*
42 | G01*
43 | X135432800Y-102781100D02*
44 | X118287800Y-102781100D01*
45 | X115747800Y-105321100D02*
46 | G75*
47 | G02X118287800Y-102781100I2540000J0D01*
48 | G01*
49 | X115747800Y-105321100D02*
50 | X115747800Y-130086100D01*
51 | M02*
52 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-F_Adhes.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Glue,Top*%
6 | %TF.FilePolarity,Positive*%
7 | %FSLAX46Y46*%
8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
9 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
10 | %MOMM*%
11 | %LPD*%
12 | G04 APERTURE LIST*
13 | %ADD10C,0.050000*%
14 | %ADD11C,0.100000*%
15 | G04 APERTURE END LIST*
16 | D10*
17 | X119557800Y-133896100D02*
18 | G75*
19 | G02X115747800Y-130086100I0J3810000D01*
20 | G01*
21 | X119557800Y-133896100D02*
22 | X177342800Y-133896100D01*
23 | X181254400Y-130086100D02*
24 | G75*
25 | G02X177342800Y-133896100I-3860800J50800D01*
26 | G01*
27 | X181254400Y-130086100D02*
28 | X181254400Y-79921100D01*
29 | X177342800Y-76111100D02*
30 | G75*
31 | G02X181254400Y-79921100I50800J-3860800D01*
32 | G01*
33 | X177342800Y-76111100D02*
34 | X140512800Y-76111100D01*
35 | X137972800Y-78651100D02*
36 | G75*
37 | G02X140512800Y-76111100I2540000J0D01*
38 | G01*
39 | X137972800Y-78651100D02*
40 | X137972800Y-100241100D01*
41 | X135432800Y-102781100D02*
42 | G75*
43 | G03X137972800Y-100241100I0J2540000D01*
44 | G01*
45 | X135432800Y-102781100D02*
46 | X118287800Y-102781100D01*
47 | X115747800Y-105321100D02*
48 | G75*
49 | G02X118287800Y-102781100I2540000J0D01*
50 | G01*
51 | X115747800Y-105321100D02*
52 | X115747800Y-130086100D01*
53 | D11*
54 | G36*
55 | X171127700Y-122901200D02*
56 | G01*
57 | X171127700Y-123301000D01*
58 | X172127900Y-123301000D01*
59 | X172127900Y-122901200D01*
60 | X171127700Y-122901200D01*
61 | G37*
62 | G36*
63 | X168587700Y-79086200D02*
64 | G01*
65 | X168587700Y-79486000D01*
66 | X169587900Y-79486000D01*
67 | X169587900Y-79086200D01*
68 | X168587700Y-79086200D01*
69 | G37*
70 | M02*
71 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-F_CrtYd.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Other,User*%
6 | %FSLAX46Y46*%
7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
8 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
9 | %MOMM*%
10 | %LPD*%
11 | G04 APERTURE LIST*
12 | %ADD10C,0.050000*%
13 | G04 APERTURE END LIST*
14 | D10*
15 | X119557800Y-133896100D02*
16 | G75*
17 | G02X115747800Y-130086100I0J3810000D01*
18 | G01*
19 | X119557800Y-133896100D02*
20 | X177342800Y-133896100D01*
21 | X181254400Y-130086100D02*
22 | G75*
23 | G02X177342800Y-133896100I-3860800J50800D01*
24 | G01*
25 | X181254400Y-130086100D02*
26 | X181254400Y-79921100D01*
27 | X177342800Y-76111100D02*
28 | G75*
29 | G02X181254400Y-79921100I50800J-3860800D01*
30 | G01*
31 | X177342800Y-76111100D02*
32 | X140512800Y-76111100D01*
33 | X137972800Y-78651100D02*
34 | G75*
35 | G02X140512800Y-76111100I2540000J0D01*
36 | G01*
37 | X137972800Y-78651100D02*
38 | X137972800Y-100241100D01*
39 | X135432800Y-102781100D02*
40 | G75*
41 | G03X137972800Y-100241100I0J2540000D01*
42 | G01*
43 | X135432800Y-102781100D02*
44 | X118287800Y-102781100D01*
45 | X115747800Y-105321100D02*
46 | G75*
47 | G02X118287800Y-102781100I2540000J0D01*
48 | G01*
49 | X115747800Y-105321100D02*
50 | X115747800Y-130086100D01*
51 | M02*
52 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-F_Mask.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Soldermask,Top*%
6 | %TF.FilePolarity,Negative*%
7 | %FSLAX46Y46*%
8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
9 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
10 | %MOMM*%
11 | %LPD*%
12 | G04 APERTURE LIST*
13 | %ADD10C,0.050000*%
14 | %ADD11C,2.843200*%
15 | %ADD12C,1.727200*%
16 | %ADD13C,2.082800*%
17 | %ADD14R,2.082800X2.082800*%
18 | %ADD15R,2.003200X2.603200*%
19 | %ADD16R,1.403200X1.403200*%
20 | %ADD17R,1.703200X1.503200*%
21 | %ADD18C,4.318000*%
22 | %ADD19O,3.251200X1.727200*%
23 | %ADD20C,1.854200*%
24 | G04 APERTURE END LIST*
25 | D10*
26 | X119557800Y-133896100D02*
27 | G75*
28 | G02X115747800Y-130086100I0J3810000D01*
29 | G01*
30 | X119557800Y-133896100D02*
31 | X177342800Y-133896100D01*
32 | X181254400Y-130086100D02*
33 | G75*
34 | G02X177342800Y-133896100I-3860800J50800D01*
35 | G01*
36 | X181254400Y-130086100D02*
37 | X181254400Y-79921100D01*
38 | X177342800Y-76111100D02*
39 | G75*
40 | G02X181254400Y-79921100I50800J-3860800D01*
41 | G01*
42 | X177342800Y-76111100D02*
43 | X140512800Y-76111100D01*
44 | X137972800Y-78651100D02*
45 | G75*
46 | G02X140512800Y-76111100I2540000J0D01*
47 | G01*
48 | X137972800Y-78651100D02*
49 | X137972800Y-100241100D01*
50 | X135432800Y-102781100D02*
51 | G75*
52 | G03X137972800Y-100241100I0J2540000D01*
53 | G01*
54 | X135432800Y-102781100D02*
55 | X118287800Y-102781100D01*
56 | X115747800Y-105321100D02*
57 | G75*
58 | G02X118287800Y-102781100I2540000J0D01*
59 | G01*
60 | X115747800Y-105321100D02*
61 | X115747800Y-130086100D01*
62 | D11*
63 | X177749200Y-128816100D03*
64 | X119761000Y-128816100D03*
65 | X177749200Y-79794100D03*
66 | D12*
67 | X124637800Y-130086100D03*
68 | X124637800Y-127546100D03*
69 | X127177800Y-130086100D03*
70 | X127177800Y-127546100D03*
71 | X129717800Y-130086100D03*
72 | X129717800Y-127546100D03*
73 | X132257800Y-130086100D03*
74 | X132257800Y-127546100D03*
75 | X134797800Y-130086100D03*
76 | X134797800Y-127546100D03*
77 | X137337800Y-130086100D03*
78 | X137337800Y-127546100D03*
79 | X139877800Y-130086100D03*
80 | X139877800Y-127546100D03*
81 | X142417800Y-130086100D03*
82 | X142417800Y-127546100D03*
83 | X144957800Y-130086100D03*
84 | X144957800Y-127546100D03*
85 | X147497800Y-130086100D03*
86 | X147497800Y-127546100D03*
87 | X150037800Y-130086100D03*
88 | X150037800Y-127546100D03*
89 | X152577800Y-130086100D03*
90 | X152577800Y-127546100D03*
91 | X155117800Y-130086100D03*
92 | X155117800Y-127546100D03*
93 | X157657800Y-130086100D03*
94 | X157657800Y-127546100D03*
95 | X160197800Y-130086100D03*
96 | X160197800Y-127546100D03*
97 | X162737800Y-130086100D03*
98 | X162737800Y-127546100D03*
99 | X165277800Y-130086100D03*
100 | X165277800Y-127546100D03*
101 | X167817800Y-130086100D03*
102 | X167817800Y-127546100D03*
103 | X170357800Y-130086100D03*
104 | X170357800Y-127546100D03*
105 | X172897800Y-130086100D03*
106 | X172897800Y-127546100D03*
107 | D13*
108 | X165087300Y-85636100D03*
109 | D14*
110 | X162293300Y-85636100D03*
111 | D15*
112 | X161665300Y-90081100D03*
113 | X165715300Y-90081100D03*
114 | D16*
115 | X171627800Y-80336100D03*
116 | X171627800Y-78236100D03*
117 | X174167800Y-124151100D03*
118 | X174167800Y-122051100D03*
119 | D17*
120 | X171627800Y-124051100D03*
121 | X171627800Y-122151100D03*
122 | X169087800Y-80236100D03*
123 | X169087800Y-78336100D03*
124 | D13*
125 | X175437800Y-116116100D03*
126 | X172897800Y-116370100D03*
127 | X170357800Y-116116100D03*
128 | X167817800Y-116370100D03*
129 | X165277800Y-116116100D03*
130 | X160197800Y-116116100D03*
131 | X157657800Y-116370100D03*
132 | X155117800Y-116116100D03*
133 | X152577800Y-116370100D03*
134 | X150037800Y-116116100D03*
135 | X144957800Y-116116100D03*
136 | X142417800Y-116370100D03*
137 | X139877800Y-116116100D03*
138 | X137337800Y-116370100D03*
139 | X134797800Y-116116100D03*
140 | X165277800Y-107226100D03*
141 | X167817800Y-106972100D03*
142 | X170357800Y-107226100D03*
143 | X172897800Y-106972100D03*
144 | X175437800Y-107226100D03*
145 | X124637800Y-107353100D03*
146 | X127177800Y-107099100D03*
147 | D14*
148 | X129717800Y-107353100D03*
149 | D18*
150 | X173627800Y-83779500D03*
151 | X177770800Y-87515700D03*
152 | X170450000Y-87541100D03*
153 | D19*
154 | X178612800Y-93891100D03*
155 | X178612800Y-96431100D03*
156 | X178612800Y-98971100D03*
157 | X178612800Y-101511100D03*
158 | D20*
159 | X147497800Y-91986100D03*
160 | X150037800Y-91986100D03*
161 | X157657800Y-91986100D03*
162 | X157657800Y-86906100D03*
163 | X150037800Y-86906100D03*
164 | X147497800Y-86906100D03*
165 | X147497800Y-100876100D03*
166 | X150037800Y-100876100D03*
167 | X157657800Y-100876100D03*
168 | X157657800Y-95796100D03*
169 | X150037800Y-95796100D03*
170 | X147497800Y-95796100D03*
171 | D13*
172 | X141782800Y-95669100D03*
173 | D14*
174 | X141782800Y-98463100D03*
175 | D13*
176 | X141782800Y-88049100D03*
177 | D14*
178 | X141782800Y-90843100D03*
179 | D13*
180 | X148767800Y-80048100D03*
181 | X146227800Y-79794100D03*
182 | X143687800Y-80048100D03*
183 | D14*
184 | X141147800Y-79794100D03*
185 | D13*
186 | X147497800Y-106972100D03*
187 | X150037800Y-107226100D03*
188 | X152577800Y-106972100D03*
189 | X155117800Y-107226100D03*
190 | X157657800Y-106972100D03*
191 | X160197800Y-107226100D03*
192 | M02*
193 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-F_Paste.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Paste,Top*%
6 | %TF.FilePolarity,Positive*%
7 | %FSLAX46Y46*%
8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
9 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
10 | %MOMM*%
11 | %LPD*%
12 | G04 APERTURE LIST*
13 | %ADD10C,0.050000*%
14 | %ADD11R,1.800000X2.400000*%
15 | %ADD12R,1.200000X1.200000*%
16 | %ADD13R,1.500000X1.300000*%
17 | G04 APERTURE END LIST*
18 | D10*
19 | X119557800Y-133896100D02*
20 | G75*
21 | G02X115747800Y-130086100I0J3810000D01*
22 | G01*
23 | X119557800Y-133896100D02*
24 | X177342800Y-133896100D01*
25 | X181254400Y-130086100D02*
26 | G75*
27 | G02X177342800Y-133896100I-3860800J50800D01*
28 | G01*
29 | X181254400Y-130086100D02*
30 | X181254400Y-79921100D01*
31 | X177342800Y-76111100D02*
32 | G75*
33 | G02X181254400Y-79921100I50800J-3860800D01*
34 | G01*
35 | X177342800Y-76111100D02*
36 | X140512800Y-76111100D01*
37 | X137972800Y-78651100D02*
38 | G75*
39 | G02X140512800Y-76111100I2540000J0D01*
40 | G01*
41 | X137972800Y-78651100D02*
42 | X137972800Y-100241100D01*
43 | X135432800Y-102781100D02*
44 | G75*
45 | G03X137972800Y-100241100I0J2540000D01*
46 | G01*
47 | X135432800Y-102781100D02*
48 | X118287800Y-102781100D01*
49 | X115747800Y-105321100D02*
50 | G75*
51 | G02X118287800Y-102781100I2540000J0D01*
52 | G01*
53 | X115747800Y-105321100D02*
54 | X115747800Y-130086100D01*
55 | D11*
56 | X161665300Y-90081100D03*
57 | X165715300Y-90081100D03*
58 | D12*
59 | X171627800Y-80336100D03*
60 | X171627800Y-78236100D03*
61 | X174167800Y-124151100D03*
62 | X174167800Y-122051100D03*
63 | D13*
64 | X171627800Y-124051100D03*
65 | X171627800Y-122151100D03*
66 | X169087800Y-80236100D03*
67 | X169087800Y-78336100D03*
68 | M02*
69 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-Margin.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Other,User*%
6 | %FSLAX46Y46*%
7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
8 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
9 | %MOMM*%
10 | %LPD*%
11 | G04 APERTURE LIST*
12 | %ADD10C,0.050000*%
13 | G04 APERTURE END LIST*
14 | D10*
15 | X119557800Y-133896100D02*
16 | G75*
17 | G02X115747800Y-130086100I0J3810000D01*
18 | G01*
19 | X119557800Y-133896100D02*
20 | X177342800Y-133896100D01*
21 | X181254400Y-130086100D02*
22 | G75*
23 | G02X177342800Y-133896100I-3860800J50800D01*
24 | G01*
25 | X181254400Y-130086100D02*
26 | X181254400Y-79921100D01*
27 | X177342800Y-76111100D02*
28 | G75*
29 | G02X181254400Y-79921100I50800J-3860800D01*
30 | G01*
31 | X177342800Y-76111100D02*
32 | X140512800Y-76111100D01*
33 | X137972800Y-78651100D02*
34 | G75*
35 | G02X140512800Y-76111100I2540000J0D01*
36 | G01*
37 | X137972800Y-78651100D02*
38 | X137972800Y-100241100D01*
39 | X135432800Y-102781100D02*
40 | G75*
41 | G03X137972800Y-100241100I0J2540000D01*
42 | G01*
43 | X135432800Y-102781100D02*
44 | X118287800Y-102781100D01*
45 | X115747800Y-105321100D02*
46 | G75*
47 | G02X118287800Y-102781100I2540000J0D01*
48 | G01*
49 | X115747800Y-105321100D02*
50 | X115747800Y-130086100D01*
51 | M02*
52 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-NPTH-drl-drl_map.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/gerber/ms_auth_breakout-NPTH-drl-drl_map.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-NPTH-drl.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,NonPlated,1,2,NPTH,Drill*%
6 | %TF.FilePolarity,Positive*%
7 | %FSLAX46Y46*%
8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
9 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
10 | %MOMM*%
11 | %LPD*%
12 | G04 APERTURE LIST*
13 | %TA.AperFunction,ComponentDrill*%
14 | %ADD10C,2.743200*%
15 | %TD*%
16 | G04 APERTURE END LIST*
17 | D10*
18 | %TO.C,@HOLE2*%
19 | X177749200Y-79794100D03*
20 | %TO.C,@HOLE1*%
21 | X119761000Y-128816100D03*
22 | %TO.C,@HOLE0*%
23 | X177749200Y-128816100D03*
24 | M02*
25 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-PTH-drl-drl_map.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/gerber/ms_auth_breakout-PTH-drl-drl_map.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/gerber/ms_auth_breakout-PTH-drl.gbr:
--------------------------------------------------------------------------------
1 | %TF.GenerationSoftware,KiCad,Pcbnew,5.1.5+dfsg1-2~bpo10+1*%
2 | %TF.CreationDate,2020-10-30T12:10:53+01:00*%
3 | %TF.ProjectId,ms_auth_breakout,6d735f61-7574-4685-9f62-7265616b6f75,1.1.0*%
4 | %TF.SameCoordinates,Original*%
5 | %TF.FileFunction,Plated,1,2,PTH,Drill*%
6 | %TF.FilePolarity,Positive*%
7 | %FSLAX46Y46*%
8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
9 | G04 Created by KiCad (PCBNEW 5.1.5+dfsg1-2~bpo10+1) date 2020-10-30 12:10:53 commit 8f6b4a8*
10 | %MOMM*%
11 | %LPD*%
12 | G04 APERTURE LIST*
13 | %TA.AperFunction,ViaDrill*%
14 | %ADD10C,0.600000*%
15 | %TD*%
16 | %TA.AperFunction,ComponentDrill*%
17 | %ADD11C,0.900000*%
18 | %TD*%
19 | %TA.AperFunction,ComponentDrill*%
20 | %ADD12C,1.016000*%
21 | %TD*%
22 | %TA.AperFunction,ComponentDrill*%
23 | %ADD13C,2.997200*%
24 | %TD*%
25 | %TA.AperFunction,ComponentDrill*%
26 | %ADD14C,3.200000*%
27 | %TD*%
28 | G04 APERTURE END LIST*
29 | D10*
30 | X117652800Y-113576100D03*
31 | X119557800Y-104051100D03*
32 | X122097800Y-110401100D03*
33 | X123685300Y-115798600D03*
34 | X124637800Y-110401100D03*
35 | X125907800Y-109766100D03*
36 | X127495300Y-115798600D03*
37 | X134797800Y-105321100D03*
38 | X135432800Y-119291100D03*
39 | X140512800Y-94208600D03*
40 | X141782800Y-119291100D03*
41 | X143052800Y-105321100D03*
42 | X144957800Y-113258600D03*
43 | X149402800Y-105321100D03*
44 | X152577800Y-84366100D03*
45 | X160197800Y-95796100D03*
46 | X160197800Y-112941100D03*
47 | X160388300Y-124371100D03*
48 | X163372800Y-101511100D03*
49 | X163372800Y-104051100D03*
50 | X164325300Y-93256100D03*
51 | X169087800Y-81826100D03*
52 | D11*
53 | %TO.C,RL2*%
54 | X147497800Y-95796100D03*
55 | X147497800Y-100876100D03*
56 | X150037800Y-95796100D03*
57 | X150037800Y-100876100D03*
58 | X157657800Y-95796100D03*
59 | X157657800Y-100876100D03*
60 | %TO.C,RL1*%
61 | X147497800Y-86906100D03*
62 | X147497800Y-91986100D03*
63 | X150037800Y-86906100D03*
64 | X150037800Y-91986100D03*
65 | X157657800Y-86906100D03*
66 | X157657800Y-91986100D03*
67 | D12*
68 | %TO.C,J3*%
69 | X134797800Y-116116100D03*
70 | X137337800Y-116370100D03*
71 | X139877800Y-116116100D03*
72 | X142417800Y-116370100D03*
73 | X144957800Y-116116100D03*
74 | %TO.C,J8*%
75 | X141147800Y-79794100D03*
76 | X143687800Y-80048100D03*
77 | X146227800Y-79794100D03*
78 | X148767800Y-80048100D03*
79 | %TO.C,J2*%
80 | X150037800Y-116116100D03*
81 | X152577800Y-116370100D03*
82 | X155117800Y-116116100D03*
83 | X157657800Y-116370100D03*
84 | X160197800Y-116116100D03*
85 | %TO.C,J4*%
86 | X165277800Y-107226100D03*
87 | X167817800Y-106972100D03*
88 | X170357800Y-107226100D03*
89 | X172897800Y-106972100D03*
90 | X175437800Y-107226100D03*
91 | %TO.C,J10*%
92 | X162293300Y-85636100D03*
93 | X165087300Y-85636100D03*
94 | %TO.C,J11*%
95 | X178612800Y-93891100D03*
96 | X178612800Y-96431100D03*
97 | X178612800Y-98971100D03*
98 | X178612800Y-101511100D03*
99 | %TO.C,J7*%
100 | X124637800Y-107353100D03*
101 | X127177800Y-107099100D03*
102 | X129717800Y-107353100D03*
103 | %TO.C,J1*%
104 | X165277800Y-116116100D03*
105 | X167817800Y-116370100D03*
106 | X170357800Y-116116100D03*
107 | X172897800Y-116370100D03*
108 | X175437800Y-116116100D03*
109 | %TO.C,J13*%
110 | X141782800Y-95669100D03*
111 | X141782800Y-98463100D03*
112 | %TO.C,J5*%
113 | X147497800Y-106972100D03*
114 | X150037800Y-107226100D03*
115 | X152577800Y-106972100D03*
116 | X155117800Y-107226100D03*
117 | X157657800Y-106972100D03*
118 | X160197800Y-107226100D03*
119 | %TO.C,J12*%
120 | X141782800Y-88049100D03*
121 | X141782800Y-90843100D03*
122 | %TO.C,J14*%
123 | X124637800Y-127546100D03*
124 | X124637800Y-130086100D03*
125 | X127177800Y-127546100D03*
126 | X127177800Y-130086100D03*
127 | X129717800Y-127546100D03*
128 | X129717800Y-130086100D03*
129 | X132257800Y-127546100D03*
130 | X132257800Y-130086100D03*
131 | X134797800Y-127546100D03*
132 | X134797800Y-130086100D03*
133 | X137337800Y-127546100D03*
134 | X137337800Y-130086100D03*
135 | X139877800Y-127546100D03*
136 | X139877800Y-130086100D03*
137 | X142417800Y-127546100D03*
138 | X142417800Y-130086100D03*
139 | X144957800Y-127546100D03*
140 | X144957800Y-130086100D03*
141 | X147497800Y-127546100D03*
142 | X147497800Y-130086100D03*
143 | X150037800Y-127546100D03*
144 | X150037800Y-130086100D03*
145 | X152577800Y-127546100D03*
146 | X152577800Y-130086100D03*
147 | X155117800Y-127546100D03*
148 | X155117800Y-130086100D03*
149 | X157657800Y-127546100D03*
150 | X157657800Y-130086100D03*
151 | X160197800Y-127546100D03*
152 | X160197800Y-130086100D03*
153 | X162737800Y-127546100D03*
154 | X162737800Y-130086100D03*
155 | X165277800Y-127546100D03*
156 | X165277800Y-130086100D03*
157 | X167817800Y-127546100D03*
158 | X167817800Y-130086100D03*
159 | X170357800Y-127546100D03*
160 | X170357800Y-130086100D03*
161 | X172897800Y-127546100D03*
162 | X172897800Y-130086100D03*
163 | D13*
164 | %TO.C,J9*%
165 | X173627800Y-83779500D03*
166 | X177770800Y-87515700D03*
167 | D14*
168 | X170450000Y-87541100D03*
169 | M02*
170 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.csv:
--------------------------------------------------------------------------------
1 | Reference, Value, Footprint, Datasheet, MPN, Manufacturer, MFN
2 | "J14","PINHD-2X20","ms_auth_breakout:2X20","","SFH11-PBPC-D20-ST-BK","SULLINS CONN SOL",""
3 | "IC1","ULN2003AD","ms_auth_breakout:SO16","","ULN2003ADR","TEXAS INSTRUMENTS",""
4 | "J10","CONN_02POLAR_LOCK","ms_auth_breakout:MOLEX-1X2_LOCK","","22-23-2021","MOLEX",""
5 | "D1","DIODE-DO-214AC","ms_auth_breakout:DO-214AC","","SS14CT-ND","ON SEMI",""
6 | "LED1","LED","ms_auth_breakout:CHIPLED_0805","","LG R971-KN-1","OSRAM",""
7 | "LED2","LED","ms_auth_breakout:CHIPLED_0805","","LG R971-KN-1","OSRAM",""
8 | "R2","560","ms_auth_breakout:R0805",""
9 | "R1","1k","ms_auth_breakout:R0805",""
10 | "J1","CONN_05POLAR_LOCK","ms_auth_breakout:MOLEX-1X5_LOCK","","22-23-2051","MOLEX",""
11 | "J2","CONN_05POLAR_LOCK","ms_auth_breakout:MOLEX-1X5_LOCK","","22-23-2051","MOLEX",""
12 | "J3","CONN_05POLAR_LOCK","ms_auth_breakout:MOLEX-1X5_LOCK","","22-23-2051","MOLEX",""
13 | "J4","CONN_05POLAR_LOCK","ms_auth_breakout:MOLEX-1X5_LOCK","","22-23-2051","MOLEX",""
14 | "J7","CONN_03POLAR_LOCK","ms_auth_breakout:MOLEX-1X3_LOCK","","22-23-2031","MOLEX",""
15 | "J9","POWER_JACKPTH_LOCK","ms_auth_breakout:POWER_JACK_PTH_LOCK","","694106301002","WURTH EL",""
16 | "C2","47u","ms_auth_breakout:C1206",""
17 | "U$1","MS_LOGO","ms_auth_breakout:MS_LOGO_VECTOR",""
18 | "Q1","DMN3023L","ms_auth_breakout:SOT23-3","","DMN3023L-7","DIODES INC",""
19 | "Q2","DMN3023L","ms_auth_breakout:SOT23-3","","DMN3023L-7","DIODES INC",""
20 | "Q3","DMN3023L","ms_auth_breakout:SOT23-3","","DMN3023L-7","DIODES INC",""
21 | "Q4","DMN3023L","ms_auth_breakout:SOT23-3","","DMN3023L-7","DIODES INC",""
22 | "LOGO1","OSHW-LOGOM","ms_auth_breakout:OSHW-LOGO-M",""
23 | "Q5","DMN3023L","ms_auth_breakout:SOT23-3","","DMN3023L-7","DIODES INC",""
24 | "Q6","DMN3023L","ms_auth_breakout:SOT23-3","","DMN3023L-7","DIODES INC",""
25 | "RL1","HFD23_SPDT","ms_auth_breakout:HFD23","","HFD23/012-1ZS","HONGFA","HF"
26 | "RL2","HFD23_SPDT","ms_auth_breakout:HFD23","","HFD23/012-1ZS","HONGFA","HF"
27 | "J13","CONN_02POLAR_LOCK","ms_auth_breakout:MOLEX-1X2_LOCK","","22-23-2021","MOLEX",""
28 | "J12","CONN_02POLAR_LOCK","ms_auth_breakout:MOLEX-1X2_LOCK","","22-23-2021","MOLEX",""
29 | "J8","CONN_04POLAR_LOCK","ms_auth_breakout:MOLEX-1X4_LOCK","","22-23-2041","MOLEX",""
30 | "D2","DIODE-DO-214AC","ms_auth_breakout:DO-214AC","","SS14CT-ND","ON SEMI",""
31 | "D3","DIODE-DO-214AC","ms_auth_breakout:DO-214AC","","SS14CT-ND","ON SEMI",""
32 | "D4","DIODE-DO-214AC","ms_auth_breakout:DO-214AC","","SS14CT-ND","ON SEMI",""
33 | "R3","10k","ms_auth_breakout:R0805",""
34 | "R4","10k","ms_auth_breakout:R0805",""
35 | "R5","10k","ms_auth_breakout:R0805",""
36 | "R6","10k","ms_auth_breakout:R0805",""
37 | "J5","CONN_06POLAR_LOCK","ms_auth_breakout:MOLEX-1X6_LOCK","","22-23-2061","MOLEX",""
38 | "U$2","US0093","ms_auth_breakout:CERT-SMALL-SILK",""
39 | "J11","BUCK_MODULEHORIZONTAL","ms_auth_breakout:BUCK_HORIZONTAL","","mp2315-module","Proto supplies",""
40 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.dcm:
--------------------------------------------------------------------------------
1 | EESchema-DOCLIB Version 2.0
2 | #
3 | #End Doc Library
4 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/ms_auth_breakout.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/BUCK_HORIZONTAL.kicad_mod:
--------------------------------------------------------------------------------
1 | (module BUCK_HORIZONTAL (layer F.Cu) (tedit 0)
2 | (descr "This includes board markings for OKI-78SR-5/1.5-W36H-C and \"12-24V To 5V 3A Step Down\" which are both horizontal modules. If you use right-angle headers, you have far less to worry about.")
3 | (fp_text reference J11 (at 0 0) (layer F.SilkS) hide
4 | (effects (font (size 1.27 1.27) (thickness 0.15)) (justify right top))
5 | )
6 | (fp_text value BUCK_MODULEHORIZONTAL (at 0 0) (layer F.SilkS) hide
7 | (effects (font (size 1.27 1.27) (thickness 0.15)) (justify right top))
8 | )
9 | (fp_line (start -1.905 6.35) (end 18.415 6.35) (layer F.SilkS) (width 0.127))
10 | (fp_line (start 18.415 6.35) (end 18.415 -3.81) (layer F.SilkS) (width 0.127))
11 | (fp_line (start 18.415 -3.81) (end -1.905 -3.81) (layer F.SilkS) (width 0.127))
12 | (fp_line (start -1.905 -3.81) (end -1.905 6.35) (layer F.SilkS) (width 0.127))
13 | (fp_text user IN (at 1.905 3.175) (layer F.SilkS)
14 | (effects (font (size 1.2065 1.2065) (thickness 0.1524)) (justify left bottom))
15 | )
16 | (fp_text user GND (at 1.905 0.635) (layer F.SilkS)
17 | (effects (font (size 1.2065 1.2065) (thickness 0.1524)) (justify left bottom))
18 | )
19 | (fp_text user OUT (at 1.905 -1.905) (layer F.SilkS)
20 | (effects (font (size 1.2065 1.2065) (thickness 0.1524)) (justify left bottom))
21 | )
22 | (fp_text user "(EN, float)" (at 1.905 5.715) (layer F.SilkS)
23 | (effects (font (size 1.2065 1.2065) (thickness 0.1524)) (justify left bottom))
24 | )
25 | (fp_line (start 2.54 -5.08) (end 2.54 5.08) (layer Dwgs.User) (width 0.127))
26 | (fp_line (start 2.54 5.08) (end 12.7 5.08) (layer Dwgs.User) (width 0.127))
27 | (fp_line (start 12.7 5.08) (end 12.7 -5.08) (layer Dwgs.User) (width 0.127))
28 | (fp_line (start 12.7 -5.08) (end 2.54 -5.08) (layer Dwgs.User) (width 0.127))
29 | (fp_line (start -1.524 3.81) (end 5.461 3.81) (layer F.SilkS) (width 0.254))
30 | (pad OUT thru_hole oval (at 0 -2.54) (size 3.048 1.524) (drill 1.016) (layers *.Cu *.Mask)
31 | (solder_mask_margin 0.1016))
32 | (pad GND thru_hole oval (at 0 0) (size 3.048 1.524) (drill 1.016) (layers *.Cu *.Mask)
33 | (solder_mask_margin 0.1016))
34 | (pad IN thru_hole oval (at 0 2.54) (size 3.048 1.524) (drill 1.016) (layers *.Cu *.Mask)
35 | (solder_mask_margin 0.1016))
36 | (pad EN thru_hole oval (at 0 5.08) (size 3.048 1.524) (drill 1.016) (layers *.Cu *.Mask)
37 | (solder_mask_margin 0.1016))
38 | )
39 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/C1206.kicad_mod:
--------------------------------------------------------------------------------
1 | (module C1206 (layer F.Cu) (tedit 0)
2 | (descr CAPACITOR)
3 | (fp_text reference C2 (at -1.27 2.54 -180) (layer F.SilkS)
4 | (effects (font (size 1.2065 1.2065) (thickness 0.09652)) (justify left bottom))
5 | )
6 | (fp_text value 47u (at -1.5875 -1.27 -180) (layer F.Fab)
7 | (effects (font (size 1.2065 1.2065) (thickness 0.09652)) (justify left bottom))
8 | )
9 | (fp_line (start -2.473 -0.983) (end 2.473 -0.983) (layer Dwgs.User) (width 0.0508))
10 | (fp_line (start 2.473 0.983) (end -2.473 0.983) (layer Dwgs.User) (width 0.0508))
11 | (fp_line (start -2.473 0.983) (end -2.473 -0.983) (layer Dwgs.User) (width 0.0508))
12 | (fp_line (start 2.473 -0.983) (end 2.473 0.983) (layer Dwgs.User) (width 0.0508))
13 | (fp_line (start -0.965 -0.787) (end 0.965 -0.787) (layer F.Fab) (width 0.1016))
14 | (fp_line (start -0.965 0.787) (end 0.965 0.787) (layer F.Fab) (width 0.1016))
15 | (fp_poly (pts (xy -1.7018 0.8509) (xy -0.9517 0.8509) (xy -0.9517 -0.8491) (xy -1.7018 -0.8491)) (layer F.Fab) (width 0))
16 | (fp_poly (pts (xy 0.9517 0.8491) (xy 1.7018 0.8491) (xy 1.7018 -0.8509) (xy 0.9517 -0.8509)) (layer F.Fab) (width 0))
17 | (fp_poly (pts (xy -0.1999 0.4001) (xy 0.1999 0.4001) (xy 0.1999 -0.4001) (xy -0.1999 -0.4001)) (layer F.Adhes) (width 0))
18 | (fp_line (start -2.54 -1.11125) (end 2.54 -1.11125) (layer F.SilkS) (width 0.127))
19 | (fp_arc (start 0.615258 0) (end 2.54 -1.11125) (angle 60) (layer F.SilkS) (width 0.127))
20 | (fp_line (start 2.54 1.11125) (end -2.54 1.11125) (layer F.SilkS) (width 0.127))
21 | (fp_arc (start -0.615258 0) (end -2.54 1.11125) (angle 60) (layer F.SilkS) (width 0.127))
22 | (pad 1 smd rect (at -1.4 0) (size 1.6 1.8) (layers F.Cu F.Paste F.Mask)
23 | (solder_mask_margin 0.1016))
24 | (pad 2 smd rect (at 1.4 0) (size 1.6 1.8) (layers F.Cu F.Paste F.Mask)
25 | (solder_mask_margin 0.1016))
26 | )
27 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/CHIPLED_0805.kicad_mod:
--------------------------------------------------------------------------------
1 | (module CHIPLED_0805 (layer F.Cu) (tedit 0)
2 | (descr "CHIPLED\nSource: http://www.osram.convergy.de/ ... LG_R971.pdf")
3 | (fp_text reference LED2 (at 2.54 2.54 90) (layer F.SilkS)
4 | (effects (font (size 0.9652 0.9652) (thickness 0.115824)) (justify left bottom))
5 | )
6 | (fp_text value LED (at 2.54 1.27 90) (layer F.Fab) hide
7 | (effects (font (size 1.2065 1.2065) (thickness 0.1016)) (justify left bottom))
8 | )
9 | (fp_arc (start 0 -0.975999) (end -0.35 -0.95) (angle -171.503091) (layer F.Fab) (width 0.1016))
10 | (fp_arc (start 0 0.975999) (end -0.35 0.95) (angle 171.503091) (layer F.Fab) (width 0.1016))
11 | (fp_line (start 0.575 -0.525) (end 0.575 0.525) (layer F.Fab) (width 0.1016))
12 | (fp_line (start -0.575 0.5) (end -0.575 -0.925) (layer F.Fab) (width 0.1016))
13 | (fp_circle (center -0.45 -0.85) (end -0.347 -0.85) (layer F.Fab) (width 0.1016))
14 | (fp_poly (pts (xy 0.3 -0.5) (xy 0.625 -0.5) (xy 0.625 -1) (xy 0.3 -1)) (layer F.Fab) (width 0))
15 | (fp_poly (pts (xy -0.325 -0.5) (xy -0.175 -0.5) (xy -0.175 -0.75) (xy -0.325 -0.75)) (layer F.Fab) (width 0))
16 | (fp_poly (pts (xy 0.175 -0.5) (xy 0.325 -0.5) (xy 0.325 -0.75) (xy 0.175 -0.75)) (layer F.Fab) (width 0))
17 | (fp_poly (pts (xy -0.2 -0.5) (xy 0.2 -0.5) (xy 0.2 -0.675) (xy -0.2 -0.675)) (layer F.Fab) (width 0))
18 | (fp_poly (pts (xy 0.3 1) (xy 0.625 1) (xy 0.625 0.5) (xy 0.3 0.5)) (layer F.Fab) (width 0))
19 | (fp_poly (pts (xy -0.625 1) (xy -0.3 1) (xy -0.3 0.5) (xy -0.625 0.5)) (layer F.Fab) (width 0))
20 | (fp_poly (pts (xy 0.175 0.75) (xy 0.325 0.75) (xy 0.325 0.5) (xy 0.175 0.5)) (layer F.Fab) (width 0))
21 | (fp_poly (pts (xy -0.325 0.75) (xy -0.175 0.75) (xy -0.175 0.5) (xy -0.325 0.5)) (layer F.Fab) (width 0))
22 | (fp_poly (pts (xy -0.2 0.675) (xy 0.2 0.675) (xy 0.2 0.5) (xy -0.2 0.5)) (layer F.Fab) (width 0))
23 | (fp_poly (pts (xy -0.6 -0.5) (xy -0.3 -0.5) (xy -0.3 -0.8) (xy -0.6 -0.8)) (layer F.Fab) (width 0))
24 | (fp_poly (pts (xy -0.625 -0.925) (xy -0.35 -0.925) (xy -0.35 -1) (xy -0.625 -1)) (layer F.Fab) (width 0))
25 | (fp_line (start -0.9525 -0.3175) (end -0.9525 -1.905) (layer F.SilkS) (width 0.127))
26 | (fp_line (start -0.9525 -1.905) (end 0.9525 -1.905) (layer F.SilkS) (width 0.127))
27 | (fp_line (start 0.9525 -1.905) (end 0.9525 -0.3175) (layer F.SilkS) (width 0.127))
28 | (fp_line (start -0.9525 0.3175) (end -0.9525 1.905) (layer F.SilkS) (width 0.127))
29 | (fp_line (start -0.9525 1.905) (end 0.9525 1.905) (layer F.SilkS) (width 0.127))
30 | (fp_line (start 0.9525 1.905) (end 0.9525 0.3175) (layer F.SilkS) (width 0.127))
31 | (fp_circle (center -0.9525 -0.9525) (end -0.8001 -0.9525) (layer F.SilkS) (width 0.127))
32 | (fp_line (start -0.635 0) (end 0 0) (layer F.SilkS) (width 0.2032))
33 | (fp_line (start 0 0) (end 0.635 0) (layer F.SilkS) (width 0.2032))
34 | (fp_line (start 0 0) (end 0 -0.3175) (layer F.SilkS) (width 0.2032))
35 | (pad C smd rect (at 0 -1.05) (size 1.2 1.2) (layers F.Cu F.Paste F.Mask)
36 | (solder_mask_margin 0.1016))
37 | (pad A smd rect (at 0 1.05) (size 1.2 1.2) (layers F.Cu F.Paste F.Mask)
38 | (solder_mask_margin 0.1016))
39 | )
40 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/DO-214AC.kicad_mod:
--------------------------------------------------------------------------------
1 | (module DO-214AC (layer F.Cu) (tedit 0)
2 | (descr "SURFACE MOUNT GENERAL RECTIFIER JEDEC DO-214AC molded platic body
\nMethod 2026
\nSource: http://www.kingtronics.com/SMD_M7/M7_SMD_4007.pdf")
3 | (fp_text reference D4 (at -2.54 -1.905) (layer F.SilkS)
4 | (effects (font (size 1.2065 1.2065) (thickness 0.1016)) (justify left bottom))
5 | )
6 | (fp_text value "" (at -2.54 3.175) (layer F.Fab)
7 | (effects (font (size 1.2065 1.2065) (thickness 0.1016)) (justify left bottom))
8 | )
9 | (fp_line (start -2.15 -1.3) (end 2.15 -1.3) (layer F.Fab) (width 0.2032))
10 | (fp_line (start 2.15 -1.3) (end 2.15 1.3) (layer F.Fab) (width 0.2032))
11 | (fp_line (start 2.15 1.3) (end -2.15 1.3) (layer F.Fab) (width 0.2032))
12 | (fp_line (start -2.15 1.3) (end -2.15 -1.3) (layer F.Fab) (width 0.2032))
13 | (fp_line (start -1.035 -1.3) (end 1.025 -1.3) (layer F.SilkS) (width 0.2032))
14 | (fp_line (start 1.025 1.3) (end -1.035 1.3) (layer F.SilkS) (width 0.2032))
15 | (fp_poly (pts (xy -2.825 1.1) (xy -2.175 1.1) (xy -2.175 -1.1) (xy -2.825 -1.1)) (layer F.Fab) (width 0))
16 | (fp_poly (pts (xy 2.825 -1.1) (xy 2.175 -1.1) (xy 2.175 1.1) (xy 2.825 1.1)) (layer F.Fab) (width 0))
17 | (fp_poly (pts (xy -1.065 1.225) (xy -0.39 1.225) (xy -0.39 -1.225) (xy -1.065 -1.225)) (layer F.SilkS) (width 0))
18 | (fp_poly (pts (xy -1.75 1.225) (xy -1.075 1.225) (xy -1.075 -1.225) (xy -1.75 -1.225)) (layer F.Fab) (width 0))
19 | (pad C smd rect (at -2.025 0) (size 1.8 2.4) (layers F.Cu F.Paste F.Mask)
20 | (solder_mask_margin 0.1016))
21 | (pad A smd rect (at 2.025 0 180) (size 1.8 2.4) (layers F.Cu F.Paste F.Mask)
22 | (solder_mask_margin 0.1016))
23 | )
24 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/HFD23.kicad_mod:
--------------------------------------------------------------------------------
1 | (module HFD23 (layer F.Cu) (tedit 0)
2 | (fp_text reference RL2 (at -1.5875 0.635) (layer F.SilkS)
3 | (effects (font (size 1.4478 1.4478) (thickness 0.115824)) (justify left bottom))
4 | )
5 | (fp_text value HFD23_SPDT (at 0 0) (layer F.SilkS) hide
6 | (effects (font (size 1.27 1.27) (thickness 0.15)))
7 | )
8 | (fp_line (start -6.25 -3.75) (end 6.25 -3.75) (layer F.SilkS) (width 0.254))
9 | (fp_line (start 6.25 -3.75) (end 6.25 3.75) (layer F.SilkS) (width 0.254))
10 | (fp_line (start 6.25 3.75) (end -6.25 3.75) (layer F.SilkS) (width 0.254))
11 | (fp_line (start -6.25 3.75) (end -6.25 -3.75) (layer F.SilkS) (width 0.254))
12 | (fp_line (start -4.5 -4.25) (end -6.75 -4.25) (layer F.SilkS) (width 0.254))
13 | (fp_line (start -6.75 -4.25) (end -6.75 -2) (layer F.SilkS) (width 0.254))
14 | (pad 1 thru_hole circle (at -5.08 -2.54) (size 1.651 1.651) (drill 0.9) (layers *.Cu *.Mask)
15 | (solder_mask_margin 0.1016))
16 | (pad 2 thru_hole circle (at -2.54 -2.54) (size 1.651 1.651) (drill 0.9) (layers *.Cu *.Mask)
17 | (solder_mask_margin 0.1016))
18 | (pad 3 thru_hole circle (at 5.08 -2.54) (size 1.651 1.651) (drill 0.9) (layers *.Cu *.Mask)
19 | (solder_mask_margin 0.1016))
20 | (pad 4 thru_hole circle (at 5.08 2.54) (size 1.651 1.651) (drill 0.9) (layers *.Cu *.Mask)
21 | (solder_mask_margin 0.1016))
22 | (pad 5 thru_hole circle (at -2.54 2.54) (size 1.651 1.651) (drill 0.9) (layers *.Cu *.Mask)
23 | (solder_mask_margin 0.1016))
24 | (pad 6 thru_hole circle (at -5.08 2.54) (size 1.651 1.651) (drill 0.9) (layers *.Cu *.Mask)
25 | (solder_mask_margin 0.1016))
26 | )
27 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/MOLEX-1X2_LOCK.kicad_mod:
--------------------------------------------------------------------------------
1 | (module MOLEX-1X2_LOCK (layer F.Cu) (tedit 0)
2 | (fp_text reference J12 (at -2.413 -2.54 -90) (layer F.SilkS)
3 | (effects (font (size 0.9652 0.9652) (thickness 0.19304)) (justify left bottom))
4 | )
5 | (fp_text value "" (at -1.27 2.794) (layer F.Fab)
6 | (effects (font (size 0.57912 0.57912) (thickness 0.115824)) (justify left top))
7 | )
8 | (fp_line (start -1.27 -3.048) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
9 | (fp_line (start 3.81 -3.048) (end 3.81 2.54) (layer F.SilkS) (width 0.127))
10 | (fp_line (start 3.81 -3.048) (end -1.27 -3.048) (layer F.SilkS) (width 0.127))
11 | (fp_line (start 3.81 2.54) (end 2.54 2.54) (layer F.SilkS) (width 0.127))
12 | (fp_line (start 2.54 2.54) (end 0 2.54) (layer F.SilkS) (width 0.127))
13 | (fp_line (start 0 2.54) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
14 | (fp_line (start 0 2.54) (end 0 1.27) (layer F.SilkS) (width 0.127))
15 | (fp_line (start 0 1.27) (end 2.54 1.27) (layer F.SilkS) (width 0.127))
16 | (fp_line (start 2.54 1.27) (end 2.54 2.54) (layer F.SilkS) (width 0.127))
17 | (fp_poly (pts (xy -0.2921 0.2921) (xy 0.2921 0.2921) (xy 0.2921 -0.2921) (xy -0.2921 -0.2921)) (layer F.Fab) (width 0))
18 | (fp_poly (pts (xy 2.2479 0.2921) (xy 2.8321 0.2921) (xy 2.8321 -0.2921) (xy 2.2479 -0.2921)) (layer F.Fab) (width 0))
19 | (pad 1 thru_hole rect (at -0.127 0) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
20 | (solder_mask_margin 0.1016))
21 | (pad 2 thru_hole circle (at 2.667 0) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
22 | (solder_mask_margin 0.1016))
23 | )
24 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/MOLEX-1X3_LOCK.kicad_mod:
--------------------------------------------------------------------------------
1 | (module MOLEX-1X3_LOCK (layer F.Cu) (tedit 0)
2 | (descr "
PTH - 3 Pin Vertical Molex Polarized Header
\nPins are offset 0.005\" from center to lock pins in place during soldering. \nDatasheet referenced for footprint: 4UCONN part # 01932
\nSpecifications:\n
- Pin count:3
\n- Pin pitch:0.1\"
\n
\nExample device(s):\n
")
3 | (fp_text reference J7 (at 5.842 2.794 -180) (layer F.SilkS)
4 | (effects (font (size 0.9652 0.9652) (thickness 0.19304)) (justify left bottom))
5 | )
6 | (fp_text value "" (at 0.889 2.794 -180) (layer F.Fab)
7 | (effects (font (size 0.57912 0.57912) (thickness 0.115824)) (justify left top))
8 | )
9 | (fp_line (start -1.27 -3.048) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
10 | (fp_line (start 6.35 -3.048) (end 6.35 2.54) (layer F.SilkS) (width 0.127))
11 | (fp_line (start 6.35 -3.048) (end -1.27 -3.048) (layer F.SilkS) (width 0.127))
12 | (fp_line (start 6.35 2.54) (end 5.08 2.54) (layer F.SilkS) (width 0.127))
13 | (fp_line (start 5.08 2.54) (end 0 2.54) (layer F.SilkS) (width 0.127))
14 | (fp_line (start 0 2.54) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
15 | (fp_line (start 0 2.54) (end 0 1.27) (layer F.SilkS) (width 0.127))
16 | (fp_line (start 0 1.27) (end 5.08 1.27) (layer F.SilkS) (width 0.127))
17 | (fp_line (start 5.08 1.27) (end 5.08 2.54) (layer F.SilkS) (width 0.127))
18 | (fp_poly (pts (xy -0.2921 0.2921) (xy 0.2921 0.2921) (xy 0.2921 -0.2921) (xy -0.2921 -0.2921)) (layer F.Fab) (width 0))
19 | (fp_poly (pts (xy 2.2479 0.2921) (xy 2.8321 0.2921) (xy 2.8321 -0.2921) (xy 2.2479 -0.2921)) (layer F.Fab) (width 0))
20 | (fp_poly (pts (xy 4.7879 0.2921) (xy 5.3721 0.2921) (xy 5.3721 -0.2921) (xy 4.7879 -0.2921)) (layer F.Fab) (width 0))
21 | (pad 1 thru_hole rect (at 0 -0.127) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
22 | (solder_mask_margin 0.1016))
23 | (pad 2 thru_hole circle (at 2.54 0.127) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
24 | (solder_mask_margin 0.1016))
25 | (pad 3 thru_hole circle (at 5.08 -0.127) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
26 | (solder_mask_margin 0.1016))
27 | )
28 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/MOLEX-1X4_LOCK.kicad_mod:
--------------------------------------------------------------------------------
1 | (module MOLEX-1X4_LOCK (layer F.Cu) (tedit 0)
2 | (fp_text reference J8 (at 9.3345 -2.032) (layer F.SilkS)
3 | (effects (font (size 0.9652 0.9652) (thickness 0.19304)) (justify left bottom))
4 | )
5 | (fp_text value "" (at 2.032 3.556) (layer F.Fab)
6 | (effects (font (size 0.57912 0.57912) (thickness 0.115824)) (justify left bottom))
7 | )
8 | (fp_line (start -1.27 -3.048) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
9 | (fp_line (start 8.89 -3.048) (end 8.89 2.54) (layer F.SilkS) (width 0.127))
10 | (fp_line (start 8.89 -3.048) (end -1.27 -3.048) (layer F.SilkS) (width 0.127))
11 | (fp_line (start 8.89 2.54) (end 7.62 2.54) (layer F.SilkS) (width 0.127))
12 | (fp_line (start 7.62 2.54) (end 0 2.54) (layer F.SilkS) (width 0.127))
13 | (fp_line (start 0 2.54) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
14 | (fp_line (start 0 2.54) (end 0 1.27) (layer F.SilkS) (width 0.127))
15 | (fp_line (start 0 1.27) (end 7.62 1.27) (layer F.SilkS) (width 0.127))
16 | (fp_line (start 7.62 1.27) (end 7.62 2.54) (layer F.SilkS) (width 0.127))
17 | (pad 1 thru_hole rect (at 0 -0.127) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
18 | (solder_mask_margin 0.1016))
19 | (pad 2 thru_hole circle (at 2.54 0.127) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
20 | (solder_mask_margin 0.1016))
21 | (pad 3 thru_hole circle (at 5.08 -0.127) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
22 | (solder_mask_margin 0.1016))
23 | (pad 4 thru_hole circle (at 7.62 0.127) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
24 | (solder_mask_margin 0.1016))
25 | )
26 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/MOLEX-1X5_LOCK.kicad_mod:
--------------------------------------------------------------------------------
1 | (module MOLEX-1X5_LOCK (layer F.Cu) (tedit 0)
2 | (descr "Molex 5-Pin Plated Through-Hole Locking Footprint
\nHoles are offset 0.005\" from center to hold pins in place during soldering.\nSpecifications:\n
- Pin count:5
\n- Pin pitch:0.1\"
\n
\nDatasheet referenced for footprint
\nExample device(s):\n
")
3 | (fp_text reference J4 (at 11.43 2.794 -180) (layer F.SilkS)
4 | (effects (font (size 0.9652 0.9652) (thickness 0.19304)) (justify left bottom))
5 | )
6 | (fp_text value "" (at 2.921 3.429 -180) (layer F.Fab)
7 | (effects (font (size 0.57912 0.57912) (thickness 0.115824)) (justify left bottom))
8 | )
9 | (fp_line (start -1.27 -3.048) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
10 | (fp_line (start 11.43 -3.048) (end 11.43 2.54) (layer F.SilkS) (width 0.127))
11 | (fp_line (start 11.43 -3.048) (end -1.27 -3.048) (layer F.SilkS) (width 0.127))
12 | (fp_line (start 11.43 2.54) (end 10.16 2.54) (layer F.SilkS) (width 0.127))
13 | (fp_line (start 10.16 2.54) (end 0 2.54) (layer F.SilkS) (width 0.127))
14 | (fp_line (start 0 2.54) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
15 | (fp_line (start 0 2.54) (end 0 1.27) (layer F.SilkS) (width 0.127))
16 | (fp_line (start 0 1.27) (end 10.16 1.27) (layer F.SilkS) (width 0.127))
17 | (fp_line (start 10.16 1.27) (end 10.16 2.54) (layer F.SilkS) (width 0.127))
18 | (fp_poly (pts (xy -0.2921 0.4191) (xy 0.2921 0.4191) (xy 0.2921 -0.1651) (xy -0.2921 -0.1651)) (layer F.Fab) (width 0))
19 | (fp_poly (pts (xy 2.2479 0.4191) (xy 2.8321 0.4191) (xy 2.8321 -0.1651) (xy 2.2479 -0.1651)) (layer F.Fab) (width 0))
20 | (fp_poly (pts (xy 4.7879 0.4191) (xy 5.3721 0.4191) (xy 5.3721 -0.1651) (xy 4.7879 -0.1651)) (layer F.Fab) (width 0))
21 | (fp_poly (pts (xy 7.3279 0.4191) (xy 7.9121 0.4191) (xy 7.9121 -0.1651) (xy 7.3279 -0.1651)) (layer F.Fab) (width 0))
22 | (fp_poly (pts (xy 9.8679 0.4191) (xy 10.4521 0.4191) (xy 10.4521 -0.1651) (xy 9.8679 -0.1651)) (layer F.Fab) (width 0))
23 | (fp_line (start -0.635 -1.27) (end 0.635 -1.27) (layer F.SilkS) (width 0.2032))
24 | (fp_line (start 0.635 -1.27) (end -0.635 -1.27) (layer B.SilkS) (width 0.2032))
25 | (pad 1 thru_hole circle (at 0 0) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
26 | (solder_mask_margin 0.1016))
27 | (pad 2 thru_hole circle (at 2.54 0.254) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
28 | (solder_mask_margin 0.1016))
29 | (pad 3 thru_hole circle (at 5.08 0) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
30 | (solder_mask_margin 0.1016))
31 | (pad 4 thru_hole circle (at 7.62 0.254) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
32 | (solder_mask_margin 0.1016))
33 | (pad 5 thru_hole circle (at 10.16 0) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
34 | (solder_mask_margin 0.1016))
35 | )
36 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/MOLEX-1X6_LOCK.kicad_mod:
--------------------------------------------------------------------------------
1 | (module MOLEX-1X6_LOCK (layer F.Cu) (tedit 0)
2 | (fp_text reference J5 (at 13.97 2.794 -180) (layer F.SilkS)
3 | (effects (font (size 0.9652 0.9652) (thickness 0.19304)) (justify left bottom))
4 | )
5 | (fp_text value "" (at 4.191 3.429 -180) (layer F.Fab)
6 | (effects (font (size 0.57912 0.57912) (thickness 0.115824)) (justify left bottom))
7 | )
8 | (fp_line (start -1.27 -3.048) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
9 | (fp_line (start 13.97 -3.048) (end 13.97 2.54) (layer F.SilkS) (width 0.127))
10 | (fp_line (start 13.97 -3.048) (end -1.27 -3.048) (layer F.SilkS) (width 0.127))
11 | (fp_line (start 13.97 2.54) (end 12.7 2.54) (layer F.SilkS) (width 0.127))
12 | (fp_line (start 12.7 2.54) (end 0 2.54) (layer F.SilkS) (width 0.127))
13 | (fp_line (start 0 2.54) (end -1.27 2.54) (layer F.SilkS) (width 0.127))
14 | (fp_line (start 0 2.54) (end 0 1.27) (layer F.SilkS) (width 0.127))
15 | (fp_line (start 0 1.27) (end 12.7 1.27) (layer F.SilkS) (width 0.127))
16 | (fp_line (start 12.7 1.27) (end 12.7 2.54) (layer F.SilkS) (width 0.127))
17 | (fp_poly (pts (xy -0.2921 0.4191) (xy 0.2921 0.4191) (xy 0.2921 -0.1651) (xy -0.2921 -0.1651)) (layer F.Fab) (width 0))
18 | (fp_poly (pts (xy 2.2479 0.4191) (xy 2.8321 0.4191) (xy 2.8321 -0.1651) (xy 2.2479 -0.1651)) (layer F.Fab) (width 0))
19 | (fp_poly (pts (xy 4.7879 0.4191) (xy 5.3721 0.4191) (xy 5.3721 -0.1651) (xy 4.7879 -0.1651)) (layer F.Fab) (width 0))
20 | (fp_poly (pts (xy 7.3279 0.4191) (xy 7.9121 0.4191) (xy 7.9121 -0.1651) (xy 7.3279 -0.1651)) (layer F.Fab) (width 0))
21 | (fp_poly (pts (xy 9.8679 0.4191) (xy 10.4521 0.4191) (xy 10.4521 -0.1651) (xy 9.8679 -0.1651)) (layer F.Fab) (width 0))
22 | (fp_poly (pts (xy 12.4079 0.4191) (xy 12.9921 0.4191) (xy 12.9921 -0.1651) (xy 12.4079 -0.1651)) (layer F.Fab) (width 0))
23 | (fp_line (start -0.635 -1.27) (end 0.635 -1.27) (layer F.SilkS) (width 0.2032))
24 | (fp_line (start 0.635 -1.27) (end -0.635 -1.27) (layer B.SilkS) (width 0.2032))
25 | (pad 1 thru_hole circle (at 0 0) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
26 | (solder_mask_margin 0.1016))
27 | (pad 2 thru_hole circle (at 2.54 0.254) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
28 | (solder_mask_margin 0.1016))
29 | (pad 3 thru_hole circle (at 5.08 0) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
30 | (solder_mask_margin 0.1016))
31 | (pad 4 thru_hole circle (at 7.62 0.254) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
32 | (solder_mask_margin 0.1016))
33 | (pad 5 thru_hole circle (at 10.16 0) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
34 | (solder_mask_margin 0.1016))
35 | (pad 6 thru_hole circle (at 12.7 0.254) (size 1.8796 1.8796) (drill 1.016) (layers *.Cu *.Mask)
36 | (solder_mask_margin 0.1016))
37 | )
38 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/MS_LOGO_VECTOR.kicad_mod:
--------------------------------------------------------------------------------
1 | (module MS_LOGO_VECTOR (layer F.Cu) (tedit 0)
2 | (fp_text reference U$1 (at 0 0) (layer F.SilkS) hide
3 | (effects (font (size 1.27 1.27) (thickness 0.15)))
4 | )
5 | (fp_text value MS_LOGO (at 0 0) (layer F.SilkS) hide
6 | (effects (font (size 1.27 1.27) (thickness 0.15)))
7 | )
8 | (fp_poly (pts (xy 0.4318 -5.5118) (xy 0.4318 -0.9652) (xy 0.444874 -0.789691) (xy 0.502928 -0.623546)
9 | (xy 0.602006 -0.478087) (xy 0.735354 -0.363228) (xy 0.893887 -0.286796) (xy 1.0668 -0.254)
10 | (xy 1.242309 -0.267074) (xy 1.408454 -0.325128) (xy 1.553913 -0.424206) (xy 1.668772 -0.557554)
11 | (xy 1.778 -0.889) (xy 1.778 -4.5974)) (layer F.SilkS) (width 0))
12 | (fp_poly (pts (xy 0.6096 -5.8166) (xy 4.6736 -3.048) (xy 4.8768 -3.2258) (xy 4.572 -3.7084)
13 | (xy 4.8514 -4.1656) (xy 5.4102 -4.1656) (xy 5.6388 -3.7846) (xy 5.6896 -4.318)
14 | (xy 1.5748 -7.1374) (xy 1.3716 -6.9342) (xy 1.6256 -6.477) (xy 1.3716 -6.0198)
15 | (xy 0.8128 -6.0198) (xy 0.5842 -6.4262)) (layer F.SilkS) (width 0))
16 | (fp_poly (pts (xy 6.2992 -3.7084) (xy 8.509 -5.207) (xy 8.509 -0.9144) (xy 8.531503 -0.743476)
17 | (xy 8.597477 -0.5842) (xy 8.702427 -0.447427) (xy 8.8392 -0.342477) (xy 8.998476 -0.276503)
18 | (xy 9.1694 -0.254) (xy 9.340324 -0.276503) (xy 9.4996 -0.342477) (xy 9.636373 -0.447427)
19 | (xy 9.741323 -0.5842) (xy 9.8298 -0.9144) (xy 9.271 -0.9144) (xy 9.271 -1.1938)
20 | (xy 9.8298 -1.1938) (xy 9.8298 -1.5748) (xy 9.398 -1.5748) (xy 9.398 -1.8288)
21 | (xy 9.8298 -1.8288) (xy 9.8298 -2.2352) (xy 9.271 -2.2352) (xy 9.271 -2.4892)
22 | (xy 9.8298 -2.4892) (xy 9.8298 -2.8702) (xy 9.398 -2.8702) (xy 9.398 -3.1242)
23 | (xy 9.8298 -3.1242) (xy 9.8298 -3.5306) (xy 9.271 -3.5306) (xy 9.271 -3.7846)
24 | (xy 9.8298 -3.7846) (xy 9.8298 -4.1656) (xy 9.398 -4.1656) (xy 9.398 -4.4196)
25 | (xy 9.8298 -4.4196) (xy 9.8298 -4.8006) (xy 9.271 -4.826) (xy 9.271 -5.08)
26 | (xy 9.8298 -5.08) (xy 9.8298 -5.461) (xy 9.398 -5.461) (xy 9.398 -5.7404)
27 | (xy 9.8298 -5.7404) (xy 9.8298 -6.1214) (xy 9.2456 -6.1214) (xy 9.2456 -6.4008)
28 | (xy 9.8298 -6.4008) (xy 9.8298 -6.5278) (xy 9.8298 -6.527799) (xy 9.79427 -6.71272)
29 | (xy 9.708414 -6.88031) (xy 9.579091 -7.017181) (xy 9.416634 -7.112395) (xy 9.234024 -7.158345)
30 | (xy 9.045851 -7.151359) (xy 8.7122 -6.985) (xy 5.5626 -4.826) (xy 5.9182 -4.572)
31 | (xy 5.918199 -4.572001) (xy 6.082646 -4.39289) (xy 6.204428 -4.182433) (xy 6.277771 -3.950606)) (layer F.SilkS) (width 0))
32 | (fp_poly (pts (xy 1.3208 -6.9342) (xy 1.5748 -7.1374) (xy 1.402732 -7.233704) (xy 1.212618 -7.286031)
33 | (xy 1.015505 -7.291339) (xy 0.82285 -7.249322) (xy 0.645848 -7.16242) (xy 0.494786 -7.035684)
34 | (xy 0.378444 -6.876479) (xy 0.303583 -6.694058) (xy 0.274553 -6.499022) (xy 0.293043 -6.302706)
35 | (xy 0.357976 -6.11652) (xy 0.465579 -5.951284) (xy 0.6096 -5.8166) (xy 0.5842 -6.5278)
36 | (xy 0.8128 -6.9342)) (layer F.SilkS) (width 0))
37 | (fp_line (start 9.8552 -0.9398) (end 9.8552 -6.4262) (layer F.SilkS) (width 0.0762))
38 | (fp_poly (pts (xy 4.6736 -3.048) (xy 4.845299 -2.954736) (xy 5.034327 -2.905271) (xy 5.229701 -2.902482)
39 | (xy 5.420065 -2.94653) (xy 5.594356 -3.034855) (xy 5.742445 -3.162324) (xy 5.855725 -3.321529)
40 | (xy 5.927614 -3.503217) (xy 5.953932 -3.69683) (xy 5.933151 -3.891115) (xy 5.866479 -4.074782)
41 | (xy 5.6134 -4.3688) (xy 5.6642 -3.7338) (xy 5.4102 -3.2512) (xy 4.9022 -3.2512)) (layer F.SilkS) (width 0))
42 | )
43 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/OSHW-LOGO-M.kicad_mod:
--------------------------------------------------------------------------------
1 | (module OSHW-LOGO-M (layer F.Cu) (tedit 0)
2 | (descr "Open-Source Hardware (OSHW) Logo - Medium - Silkscreen
\nSilkscreen logo for open-source hardware designs.
\nDevices using:\n
")
3 | (fp_text reference LOGO1 (at 0 0) (layer F.SilkS) hide
4 | (effects (font (size 1.27 1.27) (thickness 0.15)))
5 | )
6 | (fp_text value OSHW-LOGOM (at 0 0) (layer F.SilkS) hide
7 | (effects (font (size 1.27 1.27) (thickness 0.15)))
8 | )
9 | (fp_poly (pts (xy 0.6578 1.588) (xy 0.9108 1.4576) (xy 1.5392 1.97) (xy 1.97 1.5392)
10 | (xy 1.4576 0.9108) (xy 1.6747 0.3866) (xy 2.4814 0.3047) (xy 2.4814 -0.3047)
11 | (xy 1.6747 -0.3866) (xy 1.58793 -0.65772) (xy 1.4576 -0.9108) (xy 1.97 -1.5392)
12 | (xy 1.5392 -1.97) (xy 0.9108 -1.4576) (xy 0.65772 -1.58793) (xy 0.3866 -1.6747)
13 | (xy 0.3047 -2.4814) (xy -0.3047 -2.4814) (xy -0.3866 -1.6747) (xy -0.65772 -1.58793)
14 | (xy -0.9108 -1.4576) (xy -1.5392 -1.97) (xy -1.97 -1.5392) (xy -1.4576 -0.9108)
15 | (xy -1.6747 -0.3866) (xy -2.4814 -0.3047) (xy -2.4814 0.3047) (xy -1.6747 0.3866)
16 | (xy -1.4576 0.9108) (xy -1.97 1.5392) (xy -1.5392 1.97) (xy -0.9108 1.4576)
17 | (xy -0.787004 1.528046) (xy -0.6578 1.588) (xy -0.299 0.7218) (xy -0.495664 0.60394)
18 | (xy -0.649641 0.434061) (xy -0.747668 0.226796) (xy -0.7813 0) (xy -0.75891 -0.185699)
19 | (xy -0.693025 -0.360754) (xy -0.58742 -0.515133) (xy -0.448147 -0.639987) (xy -0.283191 -0.728161)
20 | (xy -0.102004 -0.7746) (xy 0.085029 -0.776643) (xy 0.267187 -0.734173) (xy 0.43403 -0.649624)
21 | (xy 0.575996 -0.527842) (xy 0.684949 -0.375807) (xy 0.754643 -0.202233) (xy 0.781084 -0.017067)
22 | (xy 0.762756 0.169076) (xy 0.70071 0.345529) (xy 0.598503 0.502178) (xy 0.299 0.7218)) (layer F.SilkS) (width 0))
23 | )
24 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/POWER_JACK_PTH_LOCK.kicad_mod:
--------------------------------------------------------------------------------
1 | (module POWER_JACK_PTH_LOCK (layer F.Cu) (tedit 0)
2 | (fp_text reference J9 (at -2.921 -11.7348 -90) (layer F.SilkS)
3 | (effects (font (size 0.9652 0.9652) (thickness 0.115824)) (justify left bottom))
4 | )
5 | (fp_text value POWER_JACKPTH_LOCK (at -1.905 -1.143) (layer F.Fab) hide
6 | (effects (font (size 0.57912 0.57912) (thickness 0.12192)) (justify left bottom))
7 | )
8 | (fp_line (start 4.3476 -14.2588) (end 2.4 -14.2588) (layer F.SilkS) (width 0.2032))
9 | (fp_line (start -4.3476 -3.2794) (end -4.3476 -0.1) (layer F.Fab) (width 0.2032))
10 | (fp_line (start 4.3476 -0.1) (end 4.3476 -3.2794) (layer F.Fab) (width 0.2032))
11 | (fp_line (start 4.3476 -0.1) (end -4.3476 -0.1) (layer F.Fab) (width 0.2032))
12 | (fp_line (start 4.3476 -3.254) (end 4.3476 -8.3) (layer F.SilkS) (width 0.2032))
13 | (fp_line (start 4.3476 -14.2588) (end 4.3476 -13) (layer F.SilkS) (width 0.2032))
14 | (fp_line (start -4.3476 -3.254) (end -4.3476 -14.2588) (layer F.SilkS) (width 0.2032))
15 | (fp_line (start -4.3476 -14.2588) (end -2.4 -14.2588) (layer F.SilkS) (width 0.2032))
16 | (fp_line (start -4.3476 -3.254) (end 4.3476 -3.254) (layer F.SilkS) (width 0.2032))
17 | (fp_poly (pts (xy 1.4732 -13.4112) (xy 1.4732 -13.8684) (xy -1.4478 -13.8684) (xy -1.4478 -13.4112)) (layer F.Fab) (width 0))
18 | (fp_poly (pts (xy 1.2192 -7.3914) (xy 1.2192 -7.6708) (xy -1.2192 -7.6708) (xy -1.2192 -7.3914)) (layer F.Fab) (width 0))
19 | (fp_poly (pts (xy 4.7498 -11.9126) (xy 4.4704 -11.9126) (xy 4.4704 -9.4742) (xy 4.7498 -9.4742)) (layer F.Fab) (width 0))
20 | (pad PWR thru_hole circle (at 0 -13.8778) (size 4.1148 4.1148) (drill 3.2) (layers *.Cu *.Mask)
21 | (solder_mask_margin 0.1016))
22 | (pad GND thru_hole circle (at 0.0254 -6.557) (size 4.1148 4.1148) (drill 2.9972) (layers *.Cu *.Mask)
23 | (solder_mask_margin 0.1016))
24 | (pad GNDBREAK thru_hole circle (at 3.7616 -10.7 90) (size 4.1148 4.1148) (drill 2.9972) (layers *.Cu *.Mask)
25 | (solder_mask_margin 0.1016))
26 | )
27 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/R0805.kicad_mod:
--------------------------------------------------------------------------------
1 | (module R0805 (layer F.Cu) (tedit 0)
2 | (descr RESISTOR)
3 | (fp_text reference R6 (at -4.7625 0.635 -180) (layer F.SilkS)
4 | (effects (font (size 1.2065 1.2065) (thickness 0.09652)) (justify left bottom))
5 | )
6 | (fp_text value 10k (at -0.635 2.54 -180) (layer F.Fab)
7 | (effects (font (size 1.2065 1.2065) (thickness 0.09652)) (justify left bottom))
8 | )
9 | (fp_line (start -0.41 -0.635) (end 0.41 -0.635) (layer F.Fab) (width 0.1524))
10 | (fp_line (start -0.41 0.635) (end 0.41 0.635) (layer F.Fab) (width 0.1524))
11 | (fp_line (start -1.81425 -0.82425) (end 1.81425 -0.82425) (layer Dwgs.User) (width 0.0508))
12 | (fp_line (start 1.81425 -0.82425) (end 1.81425 0.82425) (layer Dwgs.User) (width 0.0508))
13 | (fp_line (start 1.81425 0.82425) (end -1.81425 0.82425) (layer Dwgs.User) (width 0.0508))
14 | (fp_line (start -1.81425 0.82425) (end -1.81425 -0.82425) (layer Dwgs.User) (width 0.0508))
15 | (fp_poly (pts (xy 0.4064 0.6985) (xy 1.0564 0.6985) (xy 1.0564 -0.7015) (xy 0.4064 -0.7015)) (layer F.Fab) (width 0))
16 | (fp_poly (pts (xy -1.0668 0.6985) (xy -0.4168 0.6985) (xy -0.4168 -0.7015) (xy -1.0668 -0.7015)) (layer F.Fab) (width 0))
17 | (fp_poly (pts (xy -0.1999 0.5001) (xy 0.1999 0.5001) (xy 0.1999 -0.5001) (xy -0.1999 -0.5001)) (layer F.Adhes) (width 0))
18 | (fp_line (start -1.905 -0.9525) (end -1.905 0.9525) (layer F.SilkS) (width 0.127))
19 | (fp_line (start 1.905 0.9525) (end 1.905 -0.9525) (layer F.SilkS) (width 0.127))
20 | (fp_line (start -1.905 0.9525) (end -0.3175 0.9525) (layer F.SilkS) (width 0.127))
21 | (fp_line (start 0.3175 0.9525) (end 1.905 0.9525) (layer F.SilkS) (width 0.127))
22 | (fp_line (start 1.905 -0.9525) (end 0.3175 -0.9525) (layer F.SilkS) (width 0.127))
23 | (fp_line (start -0.3175 -0.9525) (end -1.905 -0.9525) (layer F.SilkS) (width 0.127))
24 | (pad 1 smd rect (at -0.95 0) (size 1.3 1.5) (layers F.Cu F.Paste F.Mask)
25 | (solder_mask_margin 0.1016))
26 | (pad 2 smd rect (at 0.95 0) (size 1.3 1.5) (layers F.Cu F.Paste F.Mask)
27 | (solder_mask_margin 0.1016))
28 | )
29 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/SO16.kicad_mod:
--------------------------------------------------------------------------------
1 | (module SO16 (layer F.Cu) (tedit 0)
2 | (descr "Small Outline Package")
3 | (fp_text reference IC1 (at 6.35 1.143 -90) (layer F.SilkS)
4 | (effects (font (size 0.9652 0.9652) (thickness 0.115824)) (justify left bottom))
5 | )
6 | (fp_text value ULN2003AD (at -4.064 0.635) (layer F.Fab) hide
7 | (effects (font (size 1.2065 1.2065) (thickness 0.127)) (justify left bottom))
8 | )
9 | (fp_line (start 4.699 -1.9558) (end -4.699 -1.9558) (layer F.SilkS) (width 0.1524))
10 | (fp_arc (start 4.699 1.5748) (end 4.699 1.9558) (angle -90) (layer F.SilkS) (width 0.1524))
11 | (fp_arc (start -4.699 -1.5748) (end -5.08 -1.5748) (angle 90) (layer F.SilkS) (width 0.1524))
12 | (fp_arc (start 4.699 -1.5748) (end 4.699 -1.9558) (angle 90) (layer F.SilkS) (width 0.1524))
13 | (fp_arc (start -4.699 1.5748) (end -5.08 1.5748) (angle -90) (layer F.SilkS) (width 0.1524))
14 | (fp_line (start -4.699 1.9558) (end 4.699 1.9558) (layer F.SilkS) (width 0.1524))
15 | (fp_line (start 5.08 1.5748) (end 5.08 -1.5748) (layer F.SilkS) (width 0.1524))
16 | (fp_line (start -5.08 -1.5748) (end -5.08 1.5748) (layer F.SilkS) (width 0.1524))
17 | (fp_arc (start -5.08 0) (end -5.08 -0.508) (angle 180) (layer F.SilkS) (width 0.1524))
18 | (fp_line (start -5.08 1.6002) (end 5.08 1.6002) (layer F.SilkS) (width 0.0508))
19 | (fp_poly (pts (xy -0.889 -1.9558) (xy -0.381 -1.9558) (xy -0.381 -3.0988) (xy -0.889 -3.0988)) (layer F.Fab) (width 0))
20 | (fp_poly (pts (xy -4.699 3.0988) (xy -4.191 3.0988) (xy -4.191 1.9558) (xy -4.699 1.9558)) (layer F.Fab) (width 0))
21 | (fp_poly (pts (xy -3.429 3.0988) (xy -2.921 3.0988) (xy -2.921 1.9558) (xy -3.429 1.9558)) (layer F.Fab) (width 0))
22 | (fp_poly (pts (xy -2.159 3.0734) (xy -1.651 3.0734) (xy -1.651 1.9304) (xy -2.159 1.9304)) (layer F.Fab) (width 0))
23 | (fp_poly (pts (xy -0.889 3.0988) (xy -0.381 3.0988) (xy -0.381 1.9558) (xy -0.889 1.9558)) (layer F.Fab) (width 0))
24 | (fp_poly (pts (xy -2.159 -1.9558) (xy -1.651 -1.9558) (xy -1.651 -3.0988) (xy -2.159 -3.0988)) (layer F.Fab) (width 0))
25 | (fp_poly (pts (xy -3.429 -1.9558) (xy -2.921 -1.9558) (xy -2.921 -3.0988) (xy -3.429 -3.0988)) (layer F.Fab) (width 0))
26 | (fp_poly (pts (xy -4.699 -1.9558) (xy -4.191 -1.9558) (xy -4.191 -3.0988) (xy -4.699 -3.0988)) (layer F.Fab) (width 0))
27 | (fp_poly (pts (xy 0.381 3.0988) (xy 0.889 3.0988) (xy 0.889 1.9558) (xy 0.381 1.9558)) (layer F.Fab) (width 0))
28 | (fp_poly (pts (xy 1.651 3.0988) (xy 2.159 3.0988) (xy 2.159 1.9558) (xy 1.651 1.9558)) (layer F.Fab) (width 0))
29 | (fp_poly (pts (xy 2.921 3.0988) (xy 3.429 3.0988) (xy 3.429 1.9558) (xy 2.921 1.9558)) (layer F.Fab) (width 0))
30 | (fp_poly (pts (xy 4.191 3.0988) (xy 4.699 3.0988) (xy 4.699 1.9558) (xy 4.191 1.9558)) (layer F.Fab) (width 0))
31 | (fp_poly (pts (xy 0.381 -1.9558) (xy 0.889 -1.9558) (xy 0.889 -3.0988) (xy 0.381 -3.0988)) (layer F.Fab) (width 0))
32 | (fp_poly (pts (xy 1.651 -1.9558) (xy 2.159 -1.9558) (xy 2.159 -3.0988) (xy 1.651 -3.0988)) (layer F.Fab) (width 0))
33 | (fp_poly (pts (xy 2.921 -1.9558) (xy 3.429 -1.9558) (xy 3.429 -3.0988) (xy 2.921 -3.0988)) (layer F.Fab) (width 0))
34 | (fp_poly (pts (xy 4.191 -1.9558) (xy 4.699 -1.9558) (xy 4.699 -3.0988) (xy 4.191 -3.0988)) (layer F.Fab) (width 0))
35 | (pad 1 smd rect (at -4.445 3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
36 | (solder_mask_margin 0.1016))
37 | (pad 16 smd rect (at -4.445 -3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
38 | (solder_mask_margin 0.1016))
39 | (pad 2 smd rect (at -3.175 3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
40 | (solder_mask_margin 0.1016))
41 | (pad 3 smd rect (at -1.905 3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
42 | (solder_mask_margin 0.1016))
43 | (pad 15 smd rect (at -3.175 -3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
44 | (solder_mask_margin 0.1016))
45 | (pad 14 smd rect (at -1.905 -3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
46 | (solder_mask_margin 0.1016))
47 | (pad 4 smd rect (at -0.635 3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
48 | (solder_mask_margin 0.1016))
49 | (pad 13 smd rect (at -0.635 -3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
50 | (solder_mask_margin 0.1016))
51 | (pad 5 smd rect (at 0.635 3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
52 | (solder_mask_margin 0.1016))
53 | (pad 12 smd rect (at 0.635 -3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
54 | (solder_mask_margin 0.1016))
55 | (pad 6 smd rect (at 1.905 3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
56 | (solder_mask_margin 0.1016))
57 | (pad 7 smd rect (at 3.175 3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
58 | (solder_mask_margin 0.1016))
59 | (pad 11 smd rect (at 1.905 -3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
60 | (solder_mask_margin 0.1016))
61 | (pad 10 smd rect (at 3.175 -3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
62 | (solder_mask_margin 0.1016))
63 | (pad 8 smd rect (at 4.445 3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
64 | (solder_mask_margin 0.1016))
65 | (pad 9 smd rect (at 4.445 -3.0734) (size 0.6604 2.032) (layers F.Cu F.Paste F.Mask)
66 | (solder_mask_margin 0.1016))
67 | )
68 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pretty/SOT23-3.kicad_mod:
--------------------------------------------------------------------------------
1 | (module SOT23-3 (layer F.Cu) (tedit 0)
2 | (descr SOT23-3)
3 | (fp_text reference Q6 (at -1.651 0 90) (layer F.SilkS)
4 | (effects (font (size 0.57912 0.57912) (thickness 0.12192)) (justify bottom))
5 | )
6 | (fp_text value DMN3023L (at 1.651 0 90) (layer F.Fab)
7 | (effects (font (size 0.57912 0.57912) (thickness 0.12192)) (justify top))
8 | )
9 | (fp_line (start 1.4224 -0.6604) (end 1.4224 0.6604) (layer F.Fab) (width 0.1524))
10 | (fp_line (start 1.4224 0.6604) (end -1.4224 0.6604) (layer F.Fab) (width 0.1524))
11 | (fp_line (start -1.4224 0.6604) (end -1.4224 -0.6604) (layer F.Fab) (width 0.1524))
12 | (fp_line (start -1.4224 -0.6604) (end 1.4224 -0.6604) (layer F.Fab) (width 0.1524))
13 | (fp_line (start -0.8 -0.7) (end -1.4 -0.7) (layer F.SilkS) (width 0.2032))
14 | (fp_line (start -1.4 -0.7) (end -1.4 0.1) (layer F.SilkS) (width 0.2032))
15 | (fp_line (start 0.8 -0.7) (end 1.4 -0.7) (layer F.SilkS) (width 0.2032))
16 | (fp_line (start 1.4 -0.7) (end 1.4 0.1) (layer F.SilkS) (width 0.2032))
17 | (pad 1 smd rect (at -0.95 1) (size 0.8 0.9) (layers F.Cu F.Paste F.Mask)
18 | (solder_mask_margin 0.1016))
19 | (pad 2 smd rect (at 0.95 1) (size 0.8 0.9) (layers F.Cu F.Paste F.Mask)
20 | (solder_mask_margin 0.1016))
21 | (pad 3 smd rect (at 0 -1.1) (size 0.8 0.9) (layers F.Cu F.Paste F.Mask)
22 | (solder_mask_margin 0.1016))
23 | )
24 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/ms_auth_breakout.pro:
--------------------------------------------------------------------------------
1 | update=pią, 18 wrz 2020, 11:30:01
2 | version=1
3 | last_client=kicad
4 | [general]
5 | version=1
6 | RootSch=
7 | BoardNm=
8 | [pcbnew]
9 | version=1
10 | LastNetListRead=
11 | UseCmpFile=1
12 | PadDrill=0.600000000000
13 | PadDrillOvalY=0.600000000000
14 | PadSizeH=1.500000000000
15 | PadSizeV=1.500000000000
16 | PcbTextSizeV=1.500000000000
17 | PcbTextSizeH=1.500000000000
18 | PcbTextThickness=0.300000000000
19 | ModuleTextSizeV=1.000000000000
20 | ModuleTextSizeH=1.000000000000
21 | ModuleTextSizeThickness=0.150000000000
22 | SolderMaskClearance=0.000000000000
23 | SolderMaskMinWidth=0.000000000000
24 | DrawSegmentWidth=0.200000000000
25 | BoardOutlineThickness=0.100000000000
26 | ModuleOutlineThickness=0.150000000000
27 | [cvpcb]
28 | version=1
29 | NetIExt=net
30 | [eeschema]
31 | version=1
32 | LibDir=
33 | [eeschema/libraries]
34 | [schematic_editor]
35 | version=1
36 | PageLayoutDescrFile=empty.kicad_wks
37 | PlotDirectoryName=
38 | SubpartIdSeparator=0
39 | SubpartFirstId=65
40 | NetFmtName=
41 | SpiceAjustPassiveValues=0
42 | LabSize=50
43 | ERC_TestSimilarLabels=1
44 |
--------------------------------------------------------------------------------
/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-B_Mask.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-B_Mask.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-B_SilkS.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-B_SilkS.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-Bottom.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-Bottom.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-Edge_Cuts.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-Edge_Cuts.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-F_Mask.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-F_Mask.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-F_SilkS.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-F_SilkS.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-Top.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/makerspace-auth/8e35339864a6c2a67cca6d4dc95313400de0718e/hardware/pi-hat-1/plots-pdf/ms_auth_breakout-Top.pdf
--------------------------------------------------------------------------------
/hardware/pi-hat-1/sym-lib-table:
--------------------------------------------------------------------------------
1 | (sym_lib_table
2 | (lib (name ms_auth_breakout)(type Legacy)(uri ${KIPRJMOD}/ms_auth_breakout.lib)(options "")(descr ""))
3 | )
4 |
--------------------------------------------------------------------------------
/software/LICENSE:
--------------------------------------------------------------------------------
1 | ../LICENSE
--------------------------------------------------------------------------------
/software/Makefile:
--------------------------------------------------------------------------------
1 | .ONESHELL:
2 | SOURCES=authbox setup.py
3 |
4 | ifeq ($(shell grep ^ID= /etc/os-release | cut -d = -f 2), raspbian)
5 | RASPBIAN=1
6 | PYTHON?=python3
7 | else
8 | PYTHON?=python
9 | endif
10 |
11 | .PHONY: venv
12 | venv:
13 | $(PYTHON) -m venv .venv && echo 'run `. .venv/bin/activate` to use virtualenv' || ( echo "You must install python3-venv: apt-get install python3-venv")
14 |
15 | .PHONY: setup
16 | setup:
17 | ifeq ($RASBIAN,1)
18 | if ! dpkg -s python3-numpy | grep Status | grep -q installed; then \
19 | echo ERROR: please install python3-numpy: apt-get install python3-numpy; \
20 | exit 1; \
21 | fi
22 | if ! dpkg -s libatlas-base-dev | grep Status | grep -q installed; then \
23 | echo ERROR: please install libatlas-base-dev: apt-get install libatlas-base-dev; \
24 | exit 1; \
25 | fi
26 | endif
27 | if [ -d ".venv" ]; then . .venv/bin/activate; fi
28 | ${PYTHON} -m pip install -Ur requirements-dev.txt
29 |
30 | .PHONY: test
31 | test:
32 | if [ -d ".venv" ]; then . .venv/bin/activate; fi
33 | ${PYTHON} -m coverage run -m authbox.tests $(TESTOPTS)
34 | ${PYTHON} -m coverage report
35 |
36 | .PHONY: format
37 | format:
38 | if [ -d ".venv" ]; then . .venv/bin/activate; fi
39 | ${PYTHON} -m isort $(SOURCES)
40 | ${PYTHON} -m black $(SOURCES)
41 |
42 | .PHONY: lint
43 | lint:
44 | if [ -d ".venv" ]; then . .venv/bin/activate; fi
45 | ${PYTHON} -m isort --diff $(SOURCES)
46 | ${PYTHON} -m black --check $(SOURCES)
47 | ${PYTHON} -m flake8 $(SOURCES)
48 |
--------------------------------------------------------------------------------
/software/README.md:
--------------------------------------------------------------------------------
1 | # Software
2 |
3 | For the basic walkthrough of how this code works, see https://google.github.io/makerspace-auth/client/Walkthrough.html
4 |
5 | Prerequisites:
6 |
7 | 1. Python 2.7 or 3.6+
8 | 1. `evdev` (On Raspberry Pi OS, you can install with `sudo apt install python3-evdev`)
9 | 1. `gpiozero` module
10 | 1. Make sure you're in the 'input' group to use evdev
11 | 1. Make sure you're in the gpio group if you're on a Pi
12 |
13 | Developing:
14 |
15 | 1. The easiest way is to run `make setup` and then `. .venv/bin/activate`.
16 | 1. You can also run the tests with tox, using `tox -p all`
17 | 1. The code is formatted with isort+black, run `make lint` and/or `make format`
18 | before sending pull requests.
19 |
20 |
21 | ## Protocol
22 |
23 | While using a server is optional (you can do everything with shell scripts), we
24 | use a simple HTTP-based protocol that's intended to be easy to adapt to existing
25 | systems. See https://google.github.io/makerspace-auth/server/Protocol.html
26 |
27 |
28 | ## QA example
29 |
30 | This simply flashes a light when its button is pressed. We use this to run QA
31 | on authboards once assembled, and is a very simple example of how the event loop
32 | works.
33 |
34 |
35 | ## Two-button example
36 |
37 | We determined two buttons ("on" and "off", basically) to be the minimum viable
38 | controls, and this is the version that we use at Google. If you're looking for
39 | a good jumping-off point, start here.
40 |
41 | The basic workflow is:
42 |
43 | 1. Scan badge
44 | 1. Press "on". Tool will power up.
45 | 1. Warning timer commences beeps. If you press "on" again, you get more time.
46 | 1. Otherwise, tool powers off.
47 |
48 | You should copy (or symlink) this file to ~/.authboxrc and make edits to conform
49 | to your pin numbers. The defaults are for an RDR-6081AKU (keystroking) and
50 | pi-hat-1 v1.0 hardware triggering both onbarod relays to enable devices.
51 |
52 | This example out of the box stores authorized users in a local file
53 | (See `sample_auth_check.sh`) but you likely want it to query your existing
54 | user/training database. If you'd like to use the same protocol, that's
55 | documented at
56 | https://google.github.io/makerspace-auth/server/Protocol.html and if you use
57 | curl, remember the '-f'.
58 |
59 | ## Starting on boot
60 |
61 | The simplest way that works on all distros is a cron job:
62 |
63 | # Visually
64 | pi$ crontab -e
65 | (add the following line at the end, save, and apply)
66 | @reboot cd /path/to/software; python two_button.py
67 |
68 | # Through script
69 | pi$ (crontab -l; echo "@reboot cd /path/to/software; python two_button.py") | crontab -
70 |
71 | If your distro uses systemd, you can also make a systemd unit that runs it.
72 |
--------------------------------------------------------------------------------
/software/authbox/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """
16 | Authbox client modules.
17 | """
18 |
19 | __version__ = "2.0.0"
20 |
21 | try:
22 | from gpiozero import Device
23 | del Device
24 | except ModuleNotFoundError:
25 | print("ERROR: 'gpiozero' must be installed")
26 | import sys
27 | sys.exit(1)
28 |
--------------------------------------------------------------------------------
/software/authbox/badgereader_wiegand_gpio.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Ace Monster Toys. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Wiegand based badge reader directly connected via GPIO
16 | """
17 |
18 | from __future__ import division, print_function
19 |
20 | from authbox.api import BaseWiegandPinThread
21 | from authbox.compat import queue
22 |
23 | DEFAULT_QUEUE_SIZE = 100 # more than enough for a scan
24 | DEFAULT_TIMEOUT_IN_MS = 15
25 |
26 |
27 | class WiegandGPIOReader(BaseWiegandPinThread):
28 | """Badge reader hardware abstraction.
29 |
30 | A Wiegand GPIO badge reader is defined in config as:
31 |
32 | [pins]
33 | name = WiegandGPIOReader:7:13
34 |
35 | where 7 is the D0 pin (physical numbering), and 13 is the D1 pin (also
36 | physical numbering). In this configuration the 6 pin J5 connector will be
37 | structured as follows:
38 | Pin 1: D0
39 | Pin 2: D1
40 | Pin 3: No connection
41 | Pin 4: Ground
42 | Pin 5: 12v
43 | Pin 6: No connection
44 |
45 | Pin 6 is used for the switched +12v provided by the ULN2003AD chip
46 | (L5_LOGIC). As we want to constantly power the RFID reader, there is no need
47 | to populate Pin 6.
48 |
49 | It should also be noted that most GPIO based RFID badge readers operate at 5v
50 | logic, so one should use care when connecting them to the host. Most readers
51 | communicate only from the reader to the host. If this is the case a simple
52 | voltage divider is sufficient to protect the GPIO pins on the host, in the
53 | event that two way communication is needed a level shifter should be used.
54 | """
55 |
56 | def __init__(
57 | self,
58 | event_queue,
59 | config_name,
60 | d0_pin,
61 | d1_pin,
62 | on_scan=None,
63 | queue_size=DEFAULT_QUEUE_SIZE,
64 | timeout_in_ms=DEFAULT_TIMEOUT_IN_MS,
65 | ):
66 | super(WiegandGPIOReader, self).__init__(
67 | event_queue, config_name, d0_pin, d1_pin
68 | )
69 | self._on_scan = on_scan
70 | # The limited-size queue protects from a slow leak in case of deadlock, so
71 | # we can detect and output something (just a print for now)
72 | self.bitqueue = queue.Queue(int(queue_size))
73 | self.timeout_in_seconds = float(timeout_in_ms) / 1000
74 |
75 | if self._on_scan:
76 | self.d0_input_device.when_activated = self.decode;
77 | self.d1_input_device.when_activated = self.decode;
78 |
79 | def decode(self, channel):
80 | bit = "0" if channel == self.d0_input_device else "1"
81 | try:
82 | self.bitqueue.put_nowait(bit)
83 | except queue.Full:
84 | # This shouldn't happen.
85 | print("{name} BUG: QUEUE FULL".format(name=self.__class__.__name__))
86 |
87 | def read_input(self):
88 | """
89 | This thread will perform a blocking read. If there are no bits coming in
90 | the stream, this will actually wait for them to start coming in.
91 |
92 | Args:
93 | None
94 |
95 | Returns:
96 | badge value as string of 0's and 1's.
97 | """
98 | # Wait for a first bit to come in
99 | bit = self.bitqueue.get(block=True)
100 |
101 | ## this will currently have a race condition where two cards read back
102 | ## to back as one giant card
103 | bits = [bit]
104 | while True:
105 | try:
106 | bit = self.bitqueue.get(timeout=self.timeout_in_seconds)
107 | except queue.Empty:
108 | break
109 | bits.append(bit)
110 |
111 | return "".join(bits)
112 |
113 | def run_inner(self):
114 | line = self.read_input()
115 | self.event_queue.put((self._on_scan, line))
116 |
117 | def close(self):
118 | if self.d0_input_device:
119 | self.d0_input_device.close()
120 | if self.d1_input_device:
121 | self.d1_input_device.close()
122 |
123 |
--------------------------------------------------------------------------------
/software/authbox/compat.py:
--------------------------------------------------------------------------------
1 | # Copyright 2019 Tim Hatch All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """
16 | Ease Python 3 transition by handling all the python2 differences in one place.
17 | """
18 |
19 | try:
20 | import Queue as queue
21 | except ImportError:
22 | import queue # noqa: F401
23 |
24 | try:
25 | import ConfigParser as configparser
26 | except ImportError:
27 | import configparser # noqa: F401
28 |
--------------------------------------------------------------------------------
/software/authbox/config.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Config API for Authbox.
16 |
17 | """
18 | import os.path
19 | import re
20 |
21 | from authbox.compat import configparser
22 |
23 | # TODO: This is very simplistic, supporting no escapes or indirect lookups
24 | TEMPLATE_RE = re.compile(r"{((?!\d)\w+)}")
25 | TIME_RE = re.compile(r"([\d.]+)([smhd])")
26 |
27 |
28 | def recursive_config_lookup(value, config, section, stack=None):
29 | """Looks up format references in ConfigParser objects.
30 |
31 | For the sample config:
32 |
33 | [s]
34 | k = v
35 |
36 | Args:
37 | value: The format string, e.g. passing '{k}' (and 's' for section) will return 'v'
38 | config: A ConfigParser object.
39 | section: The section in which values will be looked up.
40 | stack: Omit for client call; will be provided when recursing to check for
41 | infinite loops.
42 | Returns:
43 | A string with references replaced.
44 | """
45 | if stack is None:
46 | stack = []
47 | # Typically these are shallow, so this is efficient enough
48 | if value in stack:
49 | raise CycleError
50 | stack.append(value)
51 |
52 | def local_sub(match):
53 | return recursive_config_lookup(
54 | config.get(section, match.group(1)), config, section, stack
55 | )
56 |
57 | response = TEMPLATE_RE.sub(local_sub, value)
58 | stack.pop()
59 | return response
60 |
61 |
62 | class CycleError(Exception):
63 | pass
64 |
65 |
66 | class Config(object):
67 | # TODO more than one filename?
68 | def __init__(self, filename):
69 | self._config = configparser.RawConfigParser()
70 | if filename is not None:
71 | if not self._config.read([os.path.expanduser(filename)]):
72 | # N.b. if config existed but was invalid, we'd get
73 | # MissingSectionHeaderError or so.
74 | raise Exception("Nonexistent config", filename)
75 |
76 | def get(self, section, option):
77 | # Can raise NoOptionError, NoSectionError
78 | value = self._config.get(section, option)
79 | # Just an optimization
80 | if "{" in value:
81 | return recursive_config_lookup(value, self._config, section)
82 | else:
83 | return value
84 |
85 | @classmethod
86 | def parse_time(cls, time_string):
87 | """Parse a time string.
88 |
89 | Allowable suffixes include:
90 |
91 | s: seconds
92 | m: minutes
93 | h: hours
94 | d: days
95 |
96 | and can be mixed, e.g. 1m30s.
97 |
98 | Returns the value in seconds, as an int if possible, otherwise a float.
99 | """
100 | units = {
101 | "s": 1,
102 | "m": 60,
103 | "h": 3600,
104 | "d": 86400,
105 | }
106 | if not time_string:
107 | raise Exception("Empty time_string")
108 | elif isinstance(time_string, (int, float)):
109 | return time_string
110 | elif time_string.isdigit():
111 | # No suffix is interpreted as seconds.
112 | # TODO: This doesn't work for floats.
113 | return int(time_string)
114 | else:
115 | # Ensure that everything is matched.
116 | if TIME_RE.sub("", time_string) != "":
117 | raise Exception("Unknown time_string format", time_string)
118 | total = 0
119 | for m in TIME_RE.finditer(time_string):
120 | try:
121 | number = int(m.group(1))
122 | except ValueError:
123 | number = float(m.group(1))
124 | unit_multiplier = units[m.group(2)]
125 | total += unit_multiplier * number
126 | return total
127 |
128 | def get_int_seconds(self, section, option, default):
129 | if self._config.has_option(section, option):
130 | return self.parse_time(self.get(section, option))
131 | else:
132 | return self.parse_time(default)
133 |
--------------------------------------------------------------------------------
/software/authbox/fake_evdev_device_for_testing.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | import evdev
16 |
17 |
18 | def list_devices():
19 | yield "foo"
20 | yield "badge_scanner"
21 |
22 |
23 | class InputDevice(object):
24 | """Behaves (slightly) like an evdev device for testing other code."""
25 |
26 | def __init__(self, name):
27 | self.name = name
28 |
29 | def grab(self):
30 | pass
31 |
32 | def read_loop(self):
33 | """Always yields events that should type '8:8'."""
34 | # TODO: Make this more easily customizable, and catch where it would hang
35 | # because there are no events [either reading the wrong device, or reading a
36 | # second time]
37 | if self.name == "badge_scanner":
38 | for ev in self.type_eight():
39 | yield ev
40 | for ev in self.type_colon():
41 | yield ev
42 | for ev in self.type_eight():
43 | yield ev
44 | for ev in self.type_enter():
45 | yield ev
46 |
47 | # These were all found by logging what evdev does on Ubuntu; the timestamps
48 | # have been replaced with zeroes to make this more readable since we currently
49 | # don't use them for anything.
50 | def type_eight(self):
51 | yield evdev.events.InputEvent(0, 0, 4, 4, 458789)
52 | yield evdev.events.InputEvent(0, 0, 1, 9, 1)
53 | yield evdev.events.InputEvent(0, 0, 0, 0, 0)
54 | yield evdev.events.InputEvent(0, 0, 4, 4, 458789)
55 | yield evdev.events.InputEvent(0, 0, 1, 9, 0)
56 | yield evdev.events.InputEvent(0, 0, 0, 0, 0)
57 |
58 | def type_colon(self):
59 | yield evdev.events.InputEvent(0, 0, 4, 4, 458977)
60 | yield evdev.events.InputEvent(0, 0, 1, 42, 1)
61 | yield evdev.events.InputEvent(0, 0, 4, 4, 458803)
62 | yield evdev.events.InputEvent(0, 0, 1, 39, 1)
63 | yield evdev.events.InputEvent(0, 0, 0, 0, 0)
64 | yield evdev.events.InputEvent(0, 0, 4, 4, 458977)
65 | yield evdev.events.InputEvent(0, 0, 1, 42, 0)
66 | yield evdev.events.InputEvent(0, 0, 4, 4, 458803)
67 | yield evdev.events.InputEvent(0, 0, 1, 39, 0)
68 | yield evdev.events.InputEvent(0, 0, 0, 0, 0)
69 |
70 | def type_enter(self):
71 | yield evdev.events.InputEvent(0, 0, 4, 4, 458792)
72 | yield evdev.events.InputEvent(0, 0, 1, 28, 1)
73 | yield evdev.events.InputEvent(0, 0, 0, 0, 0)
74 | yield evdev.events.InputEvent(0, 0, 4, 4, 458792)
75 | yield evdev.events.InputEvent(0, 0, 1, 28, 0)
76 | yield evdev.events.InputEvent(0, 0, 0, 0, 0)
77 |
--------------------------------------------------------------------------------
/software/authbox/fake_gpio_for_testing.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Test helper that logs instead of altering pin states."""
16 |
17 | from __future__ import print_function
18 |
19 | import time
20 |
21 |
22 | def _log_match(a, b):
23 | return abs(a[0] - b[0]) < 0.1 and a[1] == b[1] and a[2] == b[2]
24 |
25 | class FakeTime(object):
26 | """Fake for the module 'time' so tests run faster."""
27 |
28 | def __init__(self):
29 | self.t = 0
30 |
31 | def time(self):
32 | return self.t
33 |
34 | def sleep(self, x):
35 | self.t += x
36 |
37 |
38 | # TODO: Queue patcher that also advances time
39 |
--------------------------------------------------------------------------------
/software/authbox/gpio_button.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Abstraction for blinky buttons.
16 | """
17 |
18 | from authbox.api import BasePinThread
19 | from authbox.compat import queue
20 | import gpiozero
21 | import time
22 |
23 |
24 | class Button(BasePinThread):
25 | """Button hardware abstraction.
26 |
27 | A button is defined in config as:
28 |
29 | [pins]
30 | name = Button:1:2
31 |
32 | where 1 is the active-low input pin (physical numbering), and 2 is the output
33 | pin (also physical numbering). If you have another kind of button, you
34 | probably need a different class.
35 | """
36 |
37 | def __init__(
38 | self,
39 | event_queue,
40 | config_name,
41 | input_pin,
42 | output_pin,
43 | on_down=None,
44 | blink_command_queue_cls=queue.Queue,
45 | ):
46 | super(Button, self).__init__(
47 | event_queue, config_name, int(input_pin), int(output_pin)
48 | )
49 |
50 | self._on_down = on_down
51 | self.blink_command_queue = blink_command_queue_cls()
52 | self.blink_duration = 0.5 # seconds
53 | self.blinking = False
54 | self.blink_count = 0
55 | self.steady_state = False
56 | self.gpio_led = gpiozero.LED(pin="BOARD" + str(self.output_pin))
57 | button_pin = "BOARD" + str(self.input_pin)
58 | self.gpio_button = gpiozero.Button(button_pin, bounce_time = 0.15)
59 | if self._on_down:
60 | self.gpio_button.when_pressed = self._callback
61 |
62 | def _callback(self):
63 | """Wrapper to queue events instead of calling them directly."""
64 | # If we have a callback registered, debounce the switch press
65 | if (self._on_down):
66 | # This is a de-bounce filter to prevent spurious signals from triggering the logic
67 | # Looks for 5 continuous active states (each separated by 10ms)
68 | maxcount = 15 # Look for 150ms maximum
69 | lowcount = 0 # Count the number of active states seen
70 | while ((maxcount > 0) and (lowcount <= 4)):
71 | time.sleep(0.01) # 10ms delay between each cycle
72 | maxcount = maxcount - 1 # Decrement remaining cycles
73 | if (self.gpio_button.is_pressed):
74 | lowcount = lowcount + 1 # One more low cycle detected
75 | else:
76 | lowcount = 0 # Not continuously low, reset
77 | if (lowcount > 4):
78 | self.event_queue.put((self._on_down, self))
79 |
80 | def run_inner(self):
81 | """Perform one on/off/blink pulse."""
82 | try:
83 | item = self.blink_command_queue.get(block=True, timeout=self.blink_duration)
84 | self.blinking = item[0]
85 | if self.blinking:
86 | # Always begin opposite of current state for immediate visual feedback
87 | self.gpio_led.toggle()
88 | # Calculate number of remaining on/off blink toggles after this one
89 | # A zero count means to keep blinking indefinitely
90 | self.blink_count = item[1] * 2 - 1 if item[1] else 0
91 | else:
92 | # Remember last non-blinking state of the light which will be restored
93 | # after finite blink count has completed.
94 | self.steady_state = item[1]
95 | self.gpio_led.value = item[1]
96 | except queue.Empty:
97 | if self.blinking:
98 | # If blinking a finite number of times, count each on/off transition
99 | if self.blink_count > 0:
100 | self.blink_count -= 1
101 | if self.blink_count == 0:
102 | # Ensure at the end of finite blink count we always return to
103 | # the last on/off steady state, even if a new blink was started
104 | # before a previous blink has finished.
105 | self.gpio_led.value = self.steady_state
106 | self.blinking = False
107 |
108 | # Toggle output if blinking indefinitely or finite count not exhausted
109 | if self.blinking:
110 | # When blinking, invert every timeout expiration (we might have woken
111 | # up for some other reason, but this appears to work in practice).
112 | self.gpio_led.toggle()
113 |
114 | def blink(self, count=0):
115 | """Blink the light count number of times. If count is 0 then blink
116 | indefinitely.
117 |
118 | The time for each on or off pulse is `blink_duration`."""
119 | self.blink_command_queue.put((True, count))
120 |
121 | def on(self):
122 | """Turn the light (if present) on indefinitely.
123 |
124 | If the light is currently in the blink state, it stops blinking."""
125 | self.blink_command_queue.put((False, True))
126 |
127 | def off(self):
128 | """Turn the light (if present) off indefinitely.
129 |
130 | If the light is currently in the blink state, it stops blinkin."""
131 | self.blink_command_queue.put((False, False))
132 |
133 | def is_pressed(self):
134 | """Returns True if the button is currently pressed, False otherwise."""
135 | return self.gpio_button.is_pressed
136 |
--------------------------------------------------------------------------------
/software/authbox/gpio_buzzer.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Abstraction for buzzer type outputs.
16 | """
17 | from __future__ import print_function
18 |
19 | import gpiozero
20 | import time
21 |
22 | from authbox.api import BasePinThread
23 | from authbox.compat import queue
24 |
25 | OFF = 0
26 | ON = 1
27 | BEEPING = 2
28 | # HAPPY = 3
29 | # SAD = 4
30 | BEEP = 5
31 |
32 |
33 | class Buzzer(BasePinThread):
34 | """Buzzer hardware abstraction.
35 |
36 | A buzzer is defined in config as:
37 |
38 | [pins]
39 | name = Buzzer:1
40 |
41 | where 1 is the active-high output pin. This only works with buzzers that
42 | sound when driven with DC. If you need to output a square wave, investigate
43 | gpio_tonal_buzzer.py in the source history, and making that work with pigpio
44 | for more stable frequency.
45 | """
46 |
47 | def __init__(self, event_queue, config_name, output_pin):
48 | super(Buzzer, self).__init__(event_queue, config_name, None, int(output_pin))
49 | self.set_queue = queue.Queue()
50 |
51 | self.gpio_buzzer = gpiozero.Buzzer("BOARD" + str(self.output_pin))
52 | self.gpio_buzzer.off()
53 |
54 | def run_inner(self, block=True):
55 | item = self.set_queue.get(block=block)
56 | next_mode = item[0]
57 | if next_mode == OFF:
58 | self.gpio_buzzer.off()
59 | elif next_mode == ON:
60 | self.gpio_buzzer.on()
61 | elif next_mode in (BEEP, BEEPING):
62 | # As-is, this provides a logic HIGH to make a 4KHz sound on PK-12N40PQ;
63 | print("Beeping")
64 | while True:
65 | if not self.set_queue.empty():
66 | print("Done beeping")
67 | break
68 | self.gpio_buzzer.on()
69 | time.sleep(item[1])
70 | self.gpio_buzzer.off()
71 | time.sleep(item[2])
72 | if next_mode == BEEP:
73 | break
74 | print("...more beep")
75 | else:
76 | print("Error", next_mode)
77 |
78 | def _clear(self):
79 | # This looks like a busy-wait, but isn't because of the exception.
80 | try:
81 | while True:
82 | self.set_queue.get(block=False)
83 | except queue.Empty:
84 | pass
85 |
86 | def beepbeep(self, on_time=0.3, off_time=0.3):
87 | # rename to keep_beeping
88 | self._clear()
89 | self.set_queue.put((BEEPING, on_time, off_time))
90 |
91 | def beep(self, on_time=0.3, off_time=0.3):
92 | self._clear()
93 | self.set_queue.put((BEEP, on_time, off_time))
94 |
95 | def off(self, clear=True):
96 | if clear:
97 | self._clear()
98 | self.set_queue.put((OFF,))
99 |
100 | def on(self, clear=True):
101 | if clear:
102 | self._clear()
103 | self.set_queue.put((ON,))
104 |
--------------------------------------------------------------------------------
/software/authbox/gpio_relay.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Abstraction for relay type outputs.
16 | """
17 |
18 | import gpiozero
19 |
20 | from authbox.api import BasePinThread
21 |
22 | types = {
23 | "ActiveHigh": 1,
24 | "ActiveLow": 0,
25 | }
26 |
27 |
28 | class Relay(BasePinThread):
29 | """Relay hardware abstraction.
30 |
31 | A relay is defined in config as:
32 |
33 | [pins]
34 | name = Relay:ActiveHigh:1
35 |
36 | where ActiveHigh may instead be ActiveLow, as appropriate, and 1 is the output
37 | pin (physical numbering).
38 | """
39 |
40 | def __init__(self, event_queue, config_name, output_type, output_pin):
41 | super(Relay, self).__init__(
42 | event_queue, config_name, None, int(output_pin)
43 | )
44 | self.output_on_val = types[output_type]
45 | self.gpio_relay = gpiozero.DigitalOutputDevice("BOARD" + str(output_pin), initial_value= not types[output_type])
46 | # TODO: Push this initial setup into BasePinThread, to avoid a momentary glitch
47 | self.off()
48 |
49 | def run(self):
50 | pass # Don't need a thread
51 |
52 | def on(self):
53 | self.gpio_relay.value = self.output_on_val
54 |
55 | def off(self):
56 | self.gpio_relay.value = not self.output_on_val
57 |
--------------------------------------------------------------------------------
/software/authbox/tests/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = "1.0.0"
2 |
--------------------------------------------------------------------------------
/software/authbox/tests/__main__.py:
--------------------------------------------------------------------------------
1 | # flake8: noqa
2 | from unittest import main
3 |
4 | from authbox.tests.test_api import (
5 | ClassRegistryTest,
6 | DispatcherTest,
7 | MultiProxyTest,
8 | SplitEscapedTest,
9 | )
10 | from authbox.tests.test_badgereader_hid_keystroking import BadgereaderTest
11 | from authbox.tests.test_badgereader_wiegand_gpio import BadgereaderWiegandGPIOTest
12 | from authbox.tests.test_config import ConfigTest, RecursiveConfigParamLookupTest
13 | from authbox.tests.test_gpio_button import BlinkTest
14 | from authbox.tests.test_gpio_buzzer import BuzzerTest
15 | from authbox.tests.test_gpio_relay import RelayTest
16 | from authbox.tests.test_timer import TimerTest
17 |
18 | main(buffer=True)
19 |
--------------------------------------------------------------------------------
/software/authbox/tests/setup_mock_pin_factory.py:
--------------------------------------------------------------------------------
1 | try:
2 | from gpiozero import Device
3 | if not Device.pin_factory:
4 | from gpiozero.pins.mock import MockFactory
5 | Device.pin_factory = MockFactory()
6 | except ModuleNotFoundError:
7 | print("ERROR: 'gpiozero' must be installed")
8 | import sys
9 | sys.exit(1)
10 |
11 |
--------------------------------------------------------------------------------
/software/authbox/tests/test_api.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Tests for authbox.api"""
16 |
17 | import gpiozero
18 | import gpiozero.pins.mock
19 | import tempfile
20 | import unittest
21 |
22 | import setup_mock_pin_factory
23 |
24 | import authbox.api
25 | import authbox.config
26 | import authbox.gpio_button
27 |
28 | SAMPLE_CONFIG = b"""
29 | [pins]
30 | button_a = Button:11:38
31 | button_b = Button
32 | button_c = Button:1:2:3:4:5
33 | button_multi = Button:11:38, Button:16:37
34 | bad = MissingClass:1:2
35 | """
36 |
37 |
38 | class ClassRegistryTest(unittest.TestCase):
39 | def test_no_duplicate_names(self):
40 | short_names = {name.split(".")[-1] for name in authbox.api.CLASS_REGISTRY}
41 | self.assertEqual(len(short_names), len(authbox.api.CLASS_REGISTRY))
42 |
43 | def test_all_names_importable(self):
44 | try:
45 | import evdev
46 | del evdev
47 | except ModuleNotFoundError:
48 | self.fail("Test requires evdev, but evdev is not available")
49 |
50 | for c in authbox.api.CLASS_REGISTRY:
51 | cls = authbox.api._import(c)
52 | assert issubclass(
53 | cls, (authbox.api.BasePinThread, authbox.api.BaseDerivedThread)
54 | ), (c, cls, cls.__bases__)
55 |
56 |
57 | class DispatcherTest(unittest.TestCase):
58 | def setUp(self):
59 | with tempfile.NamedTemporaryFile() as f:
60 | f.write(SAMPLE_CONFIG)
61 | f.flush()
62 | config = authbox.config.Config(f.name)
63 | self.dispatcher = authbox.api.BaseDispatcher(config)
64 |
65 | def test_load_config_object(self):
66 | self.dispatcher.load_config_object("button_a")
67 | self.assertIsInstance(self.dispatcher.button_a, authbox.gpio_button.Button)
68 | self.assertEqual(self.dispatcher.button_a.input_pin, 11)
69 | self.assertEqual(self.dispatcher.button_a.output_pin, 38)
70 |
71 | def test_load_config_object_multiproxy(self):
72 | self.dispatcher.load_config_object("button_multi")
73 | self.assertIsInstance(self.dispatcher.button_multi, authbox.api.MultiProxy)
74 |
75 | def test_load_config_object_raises(self):
76 | # TODO: Needs a better exception
77 | self.assertRaises(Exception, lambda: self.dispatcher.load_config_object("bad"))
78 |
79 |
80 | class T(object):
81 | def __init__(self):
82 | self.called = 0
83 | self.args = None
84 | self.kwargs = None
85 |
86 | def meth(self, *args, **kwargs):
87 | self.called += 1
88 | self.args = args
89 | self.kwargs = kwargs
90 |
91 |
92 | class MultiProxyTest(unittest.TestCase):
93 | def setUp(self):
94 | self.a = T()
95 | self.b = T()
96 | self.c = T()
97 |
98 | self.mp = authbox.api.MultiProxy([self.a, self.b, self.c])
99 |
100 | def test_missing_method_behavior(self):
101 | self.mp.meth
102 | self.assertRaises(AttributeError, lambda: self.mp.foo)
103 |
104 | def test_all_are_called(self):
105 | self.mp.meth("a", key="val")
106 | self.assertEqual(self.a.args, ("a",))
107 | self.assertEqual(self.b.args, ("a",))
108 | self.assertEqual(self.c.args, ("a",))
109 |
110 |
111 | class SplitEscapedTest(unittest.TestCase):
112 | def test_normal(self):
113 | result = list(authbox.api.split_escaped("a,b,c"))
114 | self.assertEqual(result, ["a", "b", "c"])
115 |
116 | def test_preserves_whitespace(self):
117 | result = list(authbox.api.split_escaped(" a, b "))
118 | self.assertEqual(result, [" a", " b "])
119 |
120 | def test_alternate_glue(self):
121 | result = list(authbox.api.split_escaped("a|b", glue="|"))
122 | self.assertEqual(result, ["a", "b"])
123 |
124 | def test_escapes(self):
125 | result = list(authbox.api.split_escaped(r"a\\,\,b"))
126 | self.assertEqual(result, ["a\\", ",b"])
127 |
128 | def test_preserve(self):
129 | result = list(authbox.api.split_escaped(r"a\\,\,b", preserve=True))
130 | self.assertEqual(result, ["a\\\\", "\\,b"])
131 |
--------------------------------------------------------------------------------
/software/authbox/tests/test_badgereader_hid_keystroking.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Tests for authbox.badgereader_hid_keystroking"""
16 |
17 | import unittest
18 |
19 | import authbox.badgereader_hid_keystroking
20 |
21 | from authbox.compat import queue
22 |
23 |
24 | class BadgereaderTest(unittest.TestCase):
25 | def setUp(self):
26 | try:
27 | from authbox import fake_evdev_device_for_testing
28 | except ModuleNotFoundError:
29 | self.fail("Test requires evdev, but evdev is not available")
30 |
31 | authbox.badgereader_hid_keystroking.evdev.list_devices = (
32 | fake_evdev_device_for_testing.list_devices
33 | )
34 | authbox.badgereader_hid_keystroking.evdev.InputDevice = (
35 | fake_evdev_device_for_testing.InputDevice
36 | )
37 | self.q = queue.Queue()
38 | self.badgereader = authbox.badgereader_hid_keystroking.HIDKeystrokingReader(
39 | self.q, "b", "badge_scanner", on_scan=self.record
40 | )
41 | self.lines = []
42 |
43 | def record(self, line):
44 | self.lines.append(line)
45 |
46 | def test_read_loop(self):
47 | self.badgereader.run_inner()
48 | item = self.q.get(block=False)
49 | self.assertEqual(2, len(item))
50 | self.assertEqual(self.record, item[0])
51 | self.assertEqual("8:8", item[1])
52 | self.assertRaises(queue.Empty, self.q.get, block=False)
53 |
--------------------------------------------------------------------------------
/software/authbox/tests/test_badgereader_wiegand_gpio.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Tests for authbox.badgereader_wiegand_gpio"""
16 |
17 | import gpiozero
18 | import threading
19 | import time
20 | import unittest
21 |
22 | import setup_mock_pin_factory
23 |
24 | import authbox.badgereader_wiegand_gpio
25 | from authbox.compat import queue
26 |
27 |
28 | class BadgereaderWiegandGPIOTest(unittest.TestCase):
29 | def setUp(self):
30 | self.q = queue.Queue()
31 | self.b = authbox.badgereader_wiegand_gpio.WiegandGPIOReader(
32 | self.q,
33 | "b",
34 | "15",
35 | "40",
36 | on_scan=self.on_scan,
37 | )
38 |
39 | def tearDown(self):
40 | self.b.close()
41 |
42 | def on_scan(self, badge_number):
43 | pass
44 |
45 | def test_simple_scan(self):
46 | # Send a 1
47 | self.b.d0_input_device.pin.drive_low()
48 | self.b.d1_input_device.pin.drive_high()
49 | # Send a 0
50 | self.b.d1_input_device.pin.drive_low()
51 | self.b.d0_input_device.pin.drive_high()
52 | self.b.run_inner()
53 | self.assertEqual(self.q.get(block=False), (self.on_scan, "10"))
54 |
55 | def test_blocks_until_scan(self):
56 | def add_bits_later():
57 | time.sleep(0.2)
58 | # Send a 1
59 | self.b.d0_input_device.pin.drive_low()
60 | self.b.d1_input_device.pin.drive_high()
61 | # Send a 0
62 | self.b.d1_input_device.pin.drive_low()
63 | self.b.d0_input_device.pin.drive_high()
64 |
65 | t = threading.Thread(target=add_bits_later)
66 | t.start()
67 | self.b.run_inner()
68 | self.assertEqual(self.q.get(block=False), (self.on_scan, "10"))
69 |
70 | def test_limited_queue_size(self):
71 | self.b.d1_input_device.pin.drive_low()
72 | for i in range(500):
73 | # Send a 0
74 | self.b.d0_input_device.pin.drive_high()
75 | self.b.d0_input_device.pin.drive_low()
76 | self.b.run_inner()
77 | self.assertEqual(self.q.get(block=False), (self.on_scan, "0" * 100))
78 | # Make sure that state is reset.
79 | self.assertTrue(self.b.bitqueue.empty())
80 |
--------------------------------------------------------------------------------
/software/authbox/tests/test_config.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Tests for authbox.config"""
16 |
17 | import unittest
18 |
19 | import setup_mock_pin_factory
20 |
21 | import authbox.config
22 |
23 |
24 | class ConfigTest(unittest.TestCase):
25 | def test_parse_time(self):
26 | cfg = authbox.config.Config
27 | # ints
28 | self.assertEqual(61, cfg.parse_time("61"))
29 | self.assertEqual(61, cfg.parse_time("61s"))
30 | self.assertEqual(90, cfg.parse_time("1m30s"))
31 | self.assertEqual(3660, cfg.parse_time("61m"))
32 | self.assertEqual(7200, cfg.parse_time("2h"))
33 | self.assertEqual(86400, cfg.parse_time("1d"))
34 |
35 | self.assertEqual(1.5, cfg.parse_time("1.5s"))
36 | self.assertEqual(4320, cfg.parse_time("1.2h"))
37 | self.assertRaises(Exception, cfg.parse_time, "")
38 | self.assertRaises(Exception, cfg.parse_time, "30x")
39 |
40 | self.assertEqual(5, cfg.parse_time(5))
41 |
42 | def test_get_int_seconds(self):
43 | c = authbox.config.Config(None)
44 | c._config.add_section("section")
45 | c._config.set("section", "a", "15m")
46 | self.assertEqual(15 * 60, c.get_int_seconds("section", "a", 999))
47 |
48 | def test_get_int_seconds_absent(self):
49 | c = authbox.config.Config(None)
50 | self.assertEqual(999, c.get_int_seconds("section", "a", 999))
51 |
52 | def test_get(self):
53 | c = authbox.config.Config(None)
54 | c._config.add_section("section")
55 | c._config.set("section", "a", "1{b}2")
56 | c._config.set("section", "b", "x")
57 | self.assertEqual("1x2", c.get("section", "a"))
58 |
59 |
60 | class OneSectionConfig(object):
61 | def __init__(self, contents):
62 | self.contents = contents
63 |
64 | def get(self, section_name, key):
65 | if section_name == "section":
66 | return self.contents[key]
67 |
68 |
69 | class RecursiveConfigParamLookupTest(unittest.TestCase):
70 | def test_simple(self):
71 | c = OneSectionConfig({"a": "b"})
72 | self.assertEqual(
73 | "abc", authbox.config.recursive_config_lookup("abc", c, "section")
74 | )
75 | self.assertEqual(
76 | "b", authbox.config.recursive_config_lookup("{a}", c, "section")
77 | )
78 | self.assertRaises(
79 | KeyError, authbox.config.recursive_config_lookup, "{x}", c, "section"
80 | )
81 |
82 | def test_simple_left_alone(self):
83 | c = OneSectionConfig({"a": "b"})
84 | self.assertEqual(
85 | "{0} b", authbox.config.recursive_config_lookup("{0} {a}", c, "section")
86 | )
87 | self.assertEqual(
88 | "{} b", authbox.config.recursive_config_lookup("{} {a}", c, "section")
89 | )
90 |
91 | def test_recursive(self):
92 | c = OneSectionConfig(
93 | {"a": "{b}{b}", "b": "{c}2", "c": "d", "broken": "{b2}", "b2": "{missing}"}
94 | )
95 | self.assertEqual(
96 | "d2d2", authbox.config.recursive_config_lookup("{a}", c, "section")
97 | )
98 | self.assertRaises(
99 | KeyError, authbox.config.recursive_config_lookup, "{broken}", c, "section"
100 | )
101 |
102 | def test_recursive_fail(self):
103 | c = OneSectionConfig({"a": "{b}", "b": "{a}"})
104 | self.assertRaises(
105 | authbox.config.CycleError,
106 | authbox.config.recursive_config_lookup,
107 | "{a}",
108 | c,
109 | "section",
110 | )
111 |
--------------------------------------------------------------------------------
/software/authbox/tests/test_gpio_buzzer.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Tests for authbox.gpio_buzzer"""
16 |
17 | import unittest
18 |
19 | import setup_mock_pin_factory
20 |
21 | import authbox.gpio_buzzer
22 | from authbox import fake_gpio_for_testing
23 | from authbox.compat import queue
24 |
25 | class TestBuzzer(authbox.gpio_buzzer.Buzzer):
26 | def assert_states(self, expected_states):
27 | assert len(self.gpio_buzzer.pin.states) == len(expected_states)
28 | self.gpio_buzzer.pin.assert_states(expected_states)
29 |
30 | def clear_states(self):
31 | self.gpio_buzzer.pin.clear_states()
32 |
33 | def close(self):
34 | self.gpio_buzzer.close()
35 |
36 | class BuzzerTest(unittest.TestCase):
37 | def setUp(self):
38 | self.time = fake_gpio_for_testing.FakeTime()
39 | authbox.gpio_buzzer.time = self.time
40 |
41 | self.q = queue.Queue()
42 | self.b = TestBuzzer(self.q, "b", "15")
43 | self.b.clear_states()
44 |
45 | def tearDown(self):
46 | self.b.close()
47 |
48 | def test_on(self):
49 | self.time.sleep(2)
50 | self.b.on()
51 | self.b.run_inner(False)
52 | self.assertRaises(queue.Empty, self.b.run_inner, False)
53 | self.b.assert_states([False, True])
54 |
55 | def test_off(self):
56 | self.time.sleep(2)
57 | self.b.off()
58 | self.b.run_inner(False)
59 | self.assertRaises(queue.Empty, self.b.run_inner, False)
60 | self.b.assert_states([False])
61 |
62 | def test_beep(self):
63 | self.b.beep()
64 | self.b.run_inner(False)
65 | self.b.on()
66 | self.b.run_inner(False)
67 | self.assertRaises(queue.Empty, self.b.run_inner, False)
68 | self.b.assert_states([False, True, False, True])
69 |
70 | # BEEPING mode is not very testable, due to the infinite loop and empty
71 | # check. We could put this in another thread, but that's a test for another
72 | # day...
73 | # def test_beeping(self):
74 | # self.b.beepbeep()
75 | # self.b.off(clear=False) # Unusual, but avoids races in test.
76 | # self.b.run_inner(False)
77 | # # Queue is not empty.
78 | # self.fake.compare_log([
79 | # (0, 1, False), (0.3, 1, True), (0.6, 1, False)])
80 |
--------------------------------------------------------------------------------
/software/authbox/tests/test_gpio_relay.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Tests for authbox.gpio_relay"""
16 |
17 | import unittest
18 |
19 | import setup_mock_pin_factory
20 |
21 | import authbox.gpio_relay
22 | from authbox import fake_gpio_for_testing
23 | from authbox.compat import queue
24 |
25 | class TestRelay(authbox.gpio_relay.Relay):
26 | def assert_states(self, expected_states):
27 | assert len(self.gpio_relay.pin.states) == len(expected_states)
28 | self.gpio_relay.pin.assert_states(expected_states)
29 | def clear_states(self):
30 | self.gpio_relay.pin.clear_states()
31 |
32 | class RelayTest(unittest.TestCase):
33 | def setUp(self):
34 | self.time = fake_gpio_for_testing.FakeTime()
35 | self.q = queue.Queue()
36 |
37 | def test_activehigh(self):
38 | self.b = TestRelay(self.q, "b", "ActiveHigh", "15")
39 | self.b.clear_states()
40 | self.time.sleep(5)
41 | self.b.on()
42 | self.b.assert_states([False, True])
43 |
44 | def test_activelow(self):
45 | self.b = TestRelay(self.q, "b", "ActiveLow", "15")
46 | self.b.clear_states()
47 | self.time.sleep(5)
48 | self.b.on()
49 | self.b.assert_states([True, False])
50 |
--------------------------------------------------------------------------------
/software/authbox/tests/test_timer.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Tests for authbox.timer"""
16 |
17 | import unittest
18 |
19 | import setup_mock_pin_factory
20 |
21 | import authbox.timer
22 | from authbox.compat import queue
23 |
24 |
25 | class TimerTest(unittest.TestCase):
26 | def setUp(self):
27 | self.q = queue.Queue()
28 | self.t = authbox.timer.Timer(self.q, "t", self.callback)
29 |
30 | def callback(self, config_name):
31 | pass
32 |
33 | def test_set_exception(self):
34 | self.t.set(1)
35 | with self.assertRaises(Exception):
36 | self.t.set(1)
37 |
38 | def test_set(self):
39 | self.t.set(0.001)
40 | self.t.run_inner()
41 | self.assertEqual(1, self.q.qsize())
42 |
43 | def test_cancel_drains_queue(self):
44 | self.t.set_queue.put(None)
45 | self.t.cancel()
46 | self.assertTrue(self.t.set_queue.empty())
47 |
--------------------------------------------------------------------------------
/software/authbox/timer.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Abstraction around RPi.GPIO for relay type outputs.
16 | """
17 |
18 | from __future__ import print_function
19 |
20 | import threading
21 | import time
22 |
23 | from authbox.api import BaseDerivedThread
24 | from authbox.compat import queue
25 |
26 |
27 | class Timer(BaseDerivedThread):
28 | def __init__(self, event_queue, config_name, callback):
29 | super(Timer, self).__init__(event_queue, config_name)
30 | self.set_queue = queue.Queue(1)
31 | self.cancel_condition = threading.Condition()
32 | self.callback = callback
33 |
34 | def run_inner(self):
35 | # TODO: This is not robust to spurious wakeups, see details in
36 | # https://bugs.python.org/issue1175933 that
37 |
38 | # TODO add a KILL sentinel
39 | timeout = self.set_queue.get(block=True)
40 | print(self, "got", timeout)
41 | with self.cancel_condition:
42 | # Instead of a sleep we just pass it as a timeout here (so it's
43 | # interruptable if someone sets cancel_condition)
44 | t0 = time.time()
45 | self.cancel_condition.wait(timeout)
46 | expired = (time.time()) - t0 >= timeout
47 | print(self, "expired", expired)
48 | if expired:
49 | # The idea here is that we call callback once per set_queue item
50 | self.event_queue.put((self.callback, self.config_name))
51 |
52 | def set(self, delay):
53 | # TODO this should replace
54 | try:
55 | self.set_queue.put_nowait(delay)
56 | except queue.Full:
57 | raise Exception("There is already a queued timeout")
58 |
59 | def cancel(self):
60 | print(self, "cancel")
61 | with self.cancel_condition:
62 | self.cancel_condition.notify()
63 | try:
64 | while True:
65 | self.set_queue.get_nowait()
66 | except queue.Empty:
67 | pass
68 |
--------------------------------------------------------------------------------
/software/lockbox.ini:
--------------------------------------------------------------------------------
1 | # Copyright 2019-2020 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 |
16 | # Copy (or link) this file to ~/.authboxrc and make edits for your system.
17 |
18 | # Pins are physical (40-pin-header) numbers.
19 | # To pass arguments to the hardware layer, separate with colons.
20 | # To put multiple hardware on one action, just separate them with commas.
21 | #
22 | # Available hardware include
23 | # Button:in_pin:out_pin
24 | # Buzzer:out_pin
25 | # Relay:{ActiveHigh/ActiveLow}:out_pin
26 | # HIDKeystrokingReader:name
27 | #
28 |
29 | [pins]
30 | badge_reader = HIDKeystrokingReader:RFIDeas USB Keyboard
31 | # Hardware GPIO where relay is attached.
32 | output_relay = Relay:ActiveHigh:29
33 |
34 | [auth]
35 | # EDIT ME!
36 | # Unused names are just available in the template language for interpolation below.
37 | tool = LaserCutter1
38 | location = Sharktown
39 |
40 | # Requires uncommenting the server area below.
41 | api_key = 1234
42 | base_url=http://example.com
43 | # /EDIT ME
44 |
45 | # These values can use simple time formats like '1m30s' or '2h'. Their names
46 | # are used in lockbox.py
47 | duration = 1s
48 |
49 | # As written, this logs to a local file and checks against a file called
50 | # authorized.txt. This is for demo only, you probably want to write a samll
51 | # server that checks against your members/training.
52 | command = bash sample_auth_check.sh {} {tool} {duration}
53 | # If you wanted to communicate with a server, the easiest way is to call curl,
54 | # remembering the '-f' flag to make non-200's affect exit status. This example
55 | # uses our simple HTTP-based protocol, which is intended to be generic enough
56 | # to implement as a plugin for Wordpress/ColdFusion/IIS -- whatever your
57 | # existing system is using.
58 | #
59 | # base_args=api_key={api_key}&tool={tool}&location={location}
60 | # command = curl -f {base_url}/api/v1/check?{base_args}&badge_id={}&state=initial&auth_minutes={duration}
61 |
--------------------------------------------------------------------------------
/software/lockbox.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright 2019-2020 Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS-IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | """Example using a badge swipe to pop open a cabinet lock.
18 |
19 | """
20 | from __future__ import print_function
21 |
22 | import atexit
23 | import os
24 | import sys
25 | import subprocess
26 | import shlex
27 |
28 | from authbox.api import BaseDispatcher
29 | from authbox.config import Config
30 | from authbox.timer import Timer
31 |
32 | DEVNULL = open('/dev/null', 'r+')
33 |
34 | class Dispatcher(BaseDispatcher):
35 | def __init__(self, config):
36 | super(Dispatcher, self).__init__(config)
37 |
38 | self.load_config_object('badge_reader', on_scan=self.badge_scan)
39 | self.load_config_object('output_relay')
40 |
41 | self.disable_timer = Timer(self.event_queue, 'disable_timer', self.disable)
42 | # Otherwise, start them manually!
43 | self.threads.extend([self.disable_timer])
44 |
45 |
46 | def _get_command_line(self, section, key, format_args):
47 | """Constructs a command line, safely.
48 |
49 | The value can contain {key}, {}, and {5} style interpolation:
50 | - {key} will be resolved in the config.get; those are considered safe and
51 | spaces will separate args.
52 | - {} works on each arg independently (probably not what you want).
53 | - {5} works fine.
54 | """
55 | value = self.config.get(section, key)
56 | pieces = shlex.split(value)
57 | return [p.format(*format_args) for p in pieces]
58 |
59 | def badge_scan(self, badge_id):
60 | # Malicious badge "numbers" that contain spaces require this extra work.
61 | command = self._get_command_line('auth', 'command', [badge_id])
62 | # TODO timeout
63 | # TODO test with missing command
64 | rc = subprocess.call(command)
65 |
66 | if rc == 0:
67 | self.disable_timer.cancel()
68 | self.output_relay.on()
69 | self.disable_timer.set(self.config.get_int_seconds('auth', 'duration', '1s'))
70 |
71 | def disable(self, source=None):
72 | self.output_relay.off()
73 |
74 | def main(args):
75 | if not args:
76 | root = '~'
77 | else:
78 | root = args[0]
79 |
80 | config = Config(os.path.join(root, '.authboxrc'))
81 | Dispatcher(config).run_loop()
82 |
83 | if __name__ == '__main__':
84 | main(sys.argv[1:])
85 |
--------------------------------------------------------------------------------
/software/qa.ini:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 |
16 | # These pins match pi-hat-1 in this repo; you should use physical pin numbers,
17 | # and they shouldn't require edits when using the same board.
18 |
19 | # For Authboard v0.4
20 | [pins]
21 | j1 = Button:11:38
22 | j2 = Button:16:37
23 | j3 = Button:32:15
24 | j4 = Button:12:40
25 | j5 = Button:13:33
26 | J6 = Button:7:31
27 | # Buzzer requires DC drive
28 | buzzer = Buzzer:35
29 | relays = Relay:ActiveHigh:29, Relay:ActiveHigh:36
30 |
--------------------------------------------------------------------------------
/software/qa.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright 2018 Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS-IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | """Example to test all the buttons.
18 |
19 | """
20 | from __future__ import print_function
21 |
22 | import sys
23 | import time
24 |
25 | from authbox.api import BaseDispatcher
26 | from authbox.config import Config
27 | from authbox.timer import Timer
28 |
29 | DEVNULL = open('/dev/null', 'r+')
30 |
31 | class Dispatcher(BaseDispatcher):
32 | def __init__(self, config):
33 | super(Dispatcher, self).__init__(config)
34 |
35 | for i in range(1, 6+1):
36 | self.load_config_object('j%d' % i, on_down=self.on_button_down)
37 |
38 | self.load_config_object('buzzer')
39 | self.load_config_object('relays')
40 | # This may be a MultiProxy, which makes this easier.
41 | self.relays.on()
42 | self.relay_value = True
43 |
44 | # Run fans for 10 seconds on startup
45 | self.relay_timer = Timer(self.event_queue, 'relay_timer', self.toggle_relays)
46 | self.relay_toggle_interval = 10
47 | self.relay_timer.set(self.relay_toggle_interval)
48 | self.threads.extend([self.relay_timer])
49 |
50 | def on_button_down(self, source):
51 | print("Button down", source)
52 | self.buzzer.beep()
53 |
54 | source.on()
55 | time.sleep(0.3)
56 | source.off()
57 |
58 | def toggle_relays(self, source):
59 | print("Toggle relay", self.relay_value)
60 | if self.relay_value:
61 | self.relays.off()
62 | self.relay_value = False
63 | else:
64 | self.relays.on()
65 | self.relay_value = True
66 | self.relay_timer.set(self.relay_toggle_interval)
67 |
68 |
69 | def main(args):
70 | if not args:
71 | config_filename = 'qa.ini'
72 | else:
73 | config_filename = args[0]
74 |
75 | config = Config(config_filename)
76 | Dispatcher(config).run_loop()
77 |
78 | if __name__ == '__main__':
79 | main(sys.argv[1:])
80 |
--------------------------------------------------------------------------------
/software/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | gpiozero==2.0
2 | nose==1.3.
3 | coverage==7.2.1
4 | evdev==1.6.1
5 | isort==5.11.5
6 | black==23.1.0 ; python_version >= '3.6'
7 | tox==3.28.0
8 | flake8==3.9.2
9 |
--------------------------------------------------------------------------------
/software/sample_auth_check.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS-IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -eu
18 |
19 | # Usage: sample_auth_check.sh
20 | #
21 | # Checks to see if exists as a line in authorized.txt, and logs to
22 | # log.txt. This is a simple check for testing, but if you talk to a server
23 | # instead you can get better metrics.
24 | #
25 | # If this script exits 0, the user is allowed, and disallowed otherwise.
26 | # Because of the set -e above, this script exits nonzero if the grep line does.
27 | #
28 | user=$1
29 | tool=$2
30 | auth_minutes=$3
31 | now=$(date)
32 |
33 | # If disk is full and we can't log, this exits nonzero.
34 | echo "$now,$1,$2,$3" >> log.txt
35 | # If user is not in the list, this exits nonzero.
36 | grep -qw "$user" authorized.txt
37 |
--------------------------------------------------------------------------------
/software/sample_deauth.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS-IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -eu
18 |
19 | # Usage: sample_deauth.sh
20 | #
21 | # Logs a deauth event. (It can't really "fail", as the client will still turn
22 | # the tool off.)
23 | #
24 | # If this script exits 0, the user is allowed, and disallowed otherwise.
25 | # Because of the set -e above, this script exits nonzero if the echo does.
26 | #
27 | user=$1
28 | tool=$2
29 | now=$(date)
30 |
31 | # If disk is full and we can't log, this exits nonzero.
32 | echo "$now,$1,$2,X" >> log.txt
33 |
--------------------------------------------------------------------------------
/software/sample_extend.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS-IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -eu
18 |
19 | # Usage: sample_extend.sh
20 | #
21 | # Checks to see if an extend is allowed. If you want to check for an upcoming
22 | # class, or limit how long sessions can be, this is the place for that. This is
23 | # a simple check for testing, but if you talk to a server instead you can get
24 | # better metrics.
25 | #
26 | # This is only called after a successful auth, so barring people losing their
27 | # membership since last check... you only need to make a decision on time.
28 | #
29 | # If this script exits 0, the user is allowed, and disallowed otherwise.
30 | # Because of the set -e above, this script exits nonzero if the echo line does.
31 | #
32 | user=$1
33 | tool=$2
34 | auth_minutes=$3
35 | now=$(date)
36 |
37 | # If disk is full and we can't log, this exits nonzero.
38 | echo "$now,$1,$2,$3,E" >> log.txt
39 |
--------------------------------------------------------------------------------
/software/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | name = authbox
3 | description = A framework for makerspace tool/door authz/authn
4 | long_description = file: README.md
5 | long_description_content_type = text/markdown
6 | license = Apache2
7 | url = https://github.com/google/makerspace-auth
8 | platforms = linux
9 |
10 | [options]
11 | packages = authbox
12 | python_requires = >=2.7,!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,!=3.5
13 |
14 | [flake8]
15 | ignore = E203, E231, E266, E302, E501, W503
16 | max-line-length = 88
17 |
18 | [isort]
19 | multi_line_output = 3
20 | include_trailing_comma = True
21 | force_grid_wrap = 0
22 | use_parentheses = True
23 | line_length = 88
24 |
25 | [tox:tox]
26 | envlist = py36, py37, py311
27 |
28 | [testenv]
29 | deps = -rrequirements-dev.txt
30 | allowlist_externals = make
31 | commands =
32 | make test
33 | setenv =
34 | py{36,37,311}: COVERAGE_FILE={envdir}/.coverage
35 |
36 | [bdist_wheel]
37 | universal = true
38 |
39 | [coverage:run]
40 | include = authbox/*
41 | omit = authbox/tests/*
42 |
43 | [coverage:report]
44 | fail_under = 90
45 | show_missing = True
46 |
--------------------------------------------------------------------------------
/software/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | with open("authbox/__init__.py") as f:
4 | for line in f:
5 | if line.startswith("__version__"):
6 | version = line.split()[-1].strip("\"'")
7 | break
8 | else:
9 | raise Exception("Could not determine version from reading authbox/__init__.py")
10 |
11 | setup(
12 | version=version
13 | # TODO python_requires=
14 | )
15 |
--------------------------------------------------------------------------------
/software/test_qa.py:
--------------------------------------------------------------------------------
1 | # Copyright 2019 Tim Hatch All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | import unittest
16 |
17 | class QATest(unittest.TestCase):
18 | # TODO
19 | def test_import(self):
20 | import qa
21 |
22 |
--------------------------------------------------------------------------------
/software/test_two_button.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | """Tests for two_button.py"""
16 |
17 | import sys
18 | import unittest
19 | import tempfile
20 | import threading
21 | import time
22 |
23 | from gpiozero import Device
24 | from gpiozero.pins.mock import MockFactory
25 |
26 | import two_button
27 |
28 | import authbox.api
29 | import authbox.badgereader_hid_keystroking
30 | from authbox import fake_gpio_for_testing
31 |
32 | SAMPLE_CONFIG = b'''
33 | [pins]
34 | on_button=Button:11:38
35 | off_button=Button:16:37
36 | enable_output=Relay:ActiveHigh:29
37 | badge_reader=HIDKeystrokingReader:badge_scanner
38 | buzzer=Buzzer:35
39 | [auth]
40 | duration=20s
41 | warning=10s
42 | extend=20s
43 |
44 | command = touch enabled
45 | extend_command = touch enabled
46 | deauth_command = rm -f enabled
47 | '''
48 |
49 | # This is the fastest way to ensure that basic logic is right, but it does not
50 | # test the use of BaseDispatcher.event_queue or the way callbacks happen on the
51 | # same thread serialized.
52 | class SimpleDispatcherTest(unittest.TestCase):
53 | def setUp(self):
54 | Device.pin_factory = MockFactory()
55 |
56 | try:
57 | from authbox import fake_evdev_device_for_testing
58 | except ModuleNotFoundError:
59 | self.fail("Test requires evdev, but evdev is not available")
60 | authbox.badgereader_hid_keystroking.evdev.list_devices = fake_evdev_device_for_testing.list_devices
61 | authbox.badgereader_hid_keystroking.evdev.InputDevice = fake_evdev_device_for_testing.InputDevice
62 |
63 | with tempfile.NamedTemporaryFile() as f:
64 | f.write(SAMPLE_CONFIG)
65 | f.flush()
66 | config = authbox.config.Config(f.name)
67 |
68 | self.dispatcher = two_button.Dispatcher(config)
69 |
70 | def is_relay_on(self):
71 | relay = getattr(self.dispatcher, "enable_output")
72 | return relay.gpio_relay.value
73 |
74 | def test_auth_flow(self):
75 | # Out of the box, relay should be off
76 | self.assertFalse(self.dispatcher.authorized)
77 | self.assertFalse(self.is_relay_on())
78 | # Badge scan sets authorized flag, but doesn't enable relay until button
79 | # press.
80 | self.dispatcher.badge_scan('1234')
81 | self.assertTrue(self.dispatcher.authorized)
82 | self.assertFalse(self.is_relay_on())
83 | # "On" button pressed
84 | self.dispatcher.on_button_down(None)
85 | self.assertTrue(self.dispatcher.authorized)
86 | self.assertTrue(self.is_relay_on())
87 | # "Off" button pressed
88 | self.dispatcher.abort(None)
89 | self.assertFalse(self.dispatcher.authorized)
90 | self.assertFalse(self.is_relay_on())
91 |
--------------------------------------------------------------------------------
/software/two_button.ini:
--------------------------------------------------------------------------------
1 | # Copyright 2017-2018 Google Inc. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS-IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 |
16 | # Copy (or link) this file to ~/.authboxrc and make edits for your system.
17 |
18 | # Pins are physical (40-pin-header) numbers.
19 | # To pass arguments to the hardware layer, separate with colons.
20 | # To put multiple hardware on one action, just separate them with commas.
21 | #
22 | # Available hardware include
23 | # Button:in_pin:out_pin
24 | # Buzzer:out_pin
25 | # Relay:{ActiveHigh/ActiveLow}:out_pin
26 | # HIDKeystrokingReader:name
27 | #
28 | [pins]
29 | # These pins match pi-hat-1 in this repo; you should use physical pin numbers,
30 | # and they shouldn't require edits when using the same board.
31 | # This is J1 on authboard v0.4+
32 | on_button = Button:11:38
33 | # This is J2 on authboard v0.4+
34 | off_button = Button:16:37
35 | # Simple beeps on J4
36 | buzzer = Buzzer:35
37 | badge_reader = HIDKeystrokingReader:HID OMNIKEY 5427 CK
38 | # For Authboard v0.4 29=J13 (small relay for interlock), 31=J12 (small relay for bofa)
39 | enable_output = Relay:ActiveHigh:29, Relay:ActiveHigh:31
40 |
41 | [auth]
42 | # EDIT ME!
43 | # Unused names are just available in the template language for interpolation below.
44 | tool = LaserCutter1
45 | location = Sharktown
46 |
47 | # Requires uncommenting the server area below.
48 | api_key = 1234
49 | base_url=http://example.com
50 | # /EDIT ME
51 |
52 | # These values can use simple time formats like '1m30s' or '2h'. Their names
53 | # are used in two_button.py
54 | duration = 15m
55 | extend = 15m
56 | warning = 30s
57 |
58 | # As written, this logs to a local file and checks against a file called
59 | # authorized.txt. This is for demo only, you probably want to write a samll
60 | # server that checks against your members/training.
61 | command = bash sample_auth_check.sh {} {tool} {duration}
62 | extend_command = bash sample_extend.sh {} {tool} {extend}
63 | deauth_command = bash sample_deauth.sh {} {tool}
64 | # If you wanted to communicate with a server, the easiest way is to call curl,
65 | # remembering the '-f' flag to make non-200's affect exit status. This example
66 | # uses our simple HTTP-based protocol, which is intended to be generic enough
67 | # to implement as a plugin for Wordpress/ColdFusion/IIS -- whatever your
68 | # existing system is using.
69 | #
70 | # base_args=api_key={api_key}&tool={tool}&location={location}
71 | # command = curl -f {base_url}/api/v1/check?{base_args}&badge_id={}&state=initial&auth_minutes={duration}
72 | # extend_command = curl -f {base_url}/api/v1/check?{base_args}&badge_id={}&state=extend&auth_minutes={extend}
73 | # deauth_command = curl -f {base_url}/api/v1/check?{base_args}&state=cancel
74 |
75 | [sounds]
76 | # This section is for sounds played by a command e.g. over the headphone jack
77 | # to a portable speaker. If you want beeps, that's using Buzzer in the pins
78 | # section instead. This is here in case you want it, but most spaces have
79 | # transitioned to using Buzzer support because it's louder and easier to wire up.
80 | enable = 0
81 | command = mplayer -loop 0 {}
82 | warning_filename = /path/to/beeping.mp3
83 | sad_filename = /path/to/sadtrombone.mp3
84 |
--------------------------------------------------------------------------------
/software/two_button.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Copyright 2017 Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS-IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | """Example using two buttons for "on" and "off" once badged.
18 |
19 | """
20 | from __future__ import print_function
21 |
22 | import atexit
23 | import os
24 | import sys
25 | import subprocess
26 | import shlex
27 |
28 | from authbox.api import BaseDispatcher
29 | from authbox.config import Config
30 | from authbox.timer import Timer
31 |
32 | DEVNULL = open('/dev/null', 'r+')
33 |
34 | class Dispatcher(BaseDispatcher):
35 | def __init__(self, config):
36 | super(Dispatcher, self).__init__(config)
37 |
38 | self.authorized = False
39 | self.load_config_object('on_button', on_down=self.on_button_down)
40 | self.load_config_object('off_button', on_down=self.abort)
41 | self.load_config_object('badge_reader', on_scan=self.badge_scan)
42 | self.load_config_object('enable_output')
43 | self.load_config_object('buzzer')
44 | self.warning_timer = Timer(self.event_queue, 'warning_timer', self.warning)
45 | self.expire_timer = Timer(self.event_queue, 'expire_timer', self.abort)
46 | self.expecting_press_timer = Timer(self.event_queue, 'expecting_press_timer', self.abort)
47 | # Otherwise, start them manually!
48 | self.threads.extend([self.warning_timer, self.expire_timer, self.expecting_press_timer])
49 |
50 | self.noise = None
51 |
52 | def _get_command_line(self, section, key, format_args):
53 | """Constructs a command line, safely.
54 |
55 | The value can contain {key}, {}, and {5} style interpolation:
56 | - {key} will be resolved in the config.get; those are considered safe and
57 | spaces will separate args.
58 | - {} works on each arg independently (probably not what you want).
59 | - {5} works fine.
60 | """
61 | value = self.config.get(section, key)
62 | pieces = shlex.split(value)
63 | return [p.format(*format_args) for p in pieces]
64 |
65 | def badge_scan(self, badge_id):
66 | # Malicious badge "numbers" that contain spaces require this extra work.
67 | command = self._get_command_line('auth', 'command', [badge_id])
68 | # TODO timeout
69 | # TODO test with missing command
70 | rc = subprocess.call(command)
71 | if rc == 0:
72 | self.buzzer.beep()
73 | self.authorized = True
74 | self.badge_id = badge_id
75 | self.expecting_press_timer.set(30)
76 | self.on_button.blink()
77 | else:
78 | self.off_button.blink(1)
79 | self.buzzer.beep()
80 | if self.noise:
81 | self.noise.kill()
82 | if self.config.get('sounds', 'enable') == '1':
83 | sound_command = self._get_command_line('sounds', 'command', [self.config.get('sounds', 'sad_filename')])
84 | self.noise = subprocess.Popen(sound_command, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL)
85 |
86 | def on_button_down(self, source):
87 | print("Button down", source)
88 | if not self.authorized:
89 | self.off_button.blink(1)
90 | self.buzzer.beep()
91 | if self.noise:
92 | self.noise.kill()
93 | if self.config.get('sounds', 'enable') == '1':
94 | sound_command = self._get_command_line('sounds', 'command', [self.config.get('sounds', 'sad_filename')])
95 | self.noise = subprocess.Popen(sound_command, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL)
96 | return
97 | self.expecting_press_timer.cancel()
98 | self.on_button.on()
99 | self.enable_output.on()
100 | self.buzzer.off()
101 | self.warning_timer.cancel()
102 | self.expire_timer.cancel()
103 | # TODO use extend time if we were already enabled, and run its command for
104 | # logging.
105 | # N.b. Duration (or extend) includes the warning time.
106 | self.warning_timer.set(self.config.get_int_seconds('auth', 'duration', '5m') -
107 | self.config.get_int_seconds('auth', 'warning', '10s'))
108 | self.expire_timer.set(self.config.get_int_seconds('auth', 'duration', '5m'))
109 | if self.noise:
110 | self.noise.kill()
111 | self.noise = None
112 |
113 | def abort(self, source):
114 | print("Abort", source)
115 | self.enable_output.off()
116 | if self.authorized:
117 | command = self._get_command_line('auth', 'deauth_command', [self.badge_id])
118 | subprocess.call(command)
119 | self.off_button.blink(1)
120 | self.buzzer.beep()
121 | self.authorized = False
122 | self.warning_timer.cancel()
123 | self.expecting_press_timer.cancel()
124 | self.expire_timer.cancel()
125 | self.on_button.off()
126 | self.buzzer.off()
127 | if self.noise:
128 | self.noise.kill()
129 | self.noise = None
130 |
131 | def warning(self, unused_source):
132 | self.buzzer.beepbeep()
133 | if self.config.get('sounds', 'enable') == '1':
134 | sound_command = self._get_command_line('sounds', 'command', [self.config.get('sounds', 'warning_filename')])
135 | self.noise = subprocess.Popen(shlex.split(sound_command), stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL)
136 | self.on_button.blink()
137 |
138 |
139 | def main(args):
140 | if not args:
141 | root = '~'
142 | else:
143 | root = args[0]
144 |
145 | config = Config(os.path.join(root, '.authboxrc'))
146 | Dispatcher(config).run_loop()
147 |
148 | if __name__ == '__main__':
149 | main(sys.argv[1:])
150 |
--------------------------------------------------------------------------------