Skip to content

Add PiControl documentation #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions docs/picontrol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
PiControl is TreeHacks' NFC check-in and attendee tracking system, used at TreeHacks 2020. With PiControl, hackers badge into various events by tapping their id cards onto "cubes" equipped with NFC readers.

## ID badges

At TreeHacks 2020, we printed a custom badge for every hacker. We used [these pvc id cards](https://store.gototags.com/nfc-pvc-badge-vertical) and an ID card printer (TODO: which one? although any should work).

The process we eventually used relied on the hardware IDs for each card being unique. This means that NTAG210-215 and MIFARE cards should work, but to be safe you should check the specification for the protocol you're planning on using to make sure that there won't be any ID collisions. From our research, it seems that most manufacturers like to assign IDs in sequence, but that's obviously not guaranteed.

## Hardware

Our hardware "cube" were assembled from the following:

- A plastic cube case. These were surprisingly hard to find, so we bought [these](https://www.amazon.com/Mr-Go-Rechargeable-Soothing-Decorative-Nightstand/dp/B01E7685IG/ref=sr_1_2?dchild=1&keywords=Mr.%2BGO%2Blight%2Bcube&qid=1592967810&sr=8-2&th=1) and replaced their internals with our hardware.

- Raspberry Pi Model 3b+ (but any Raspberry Pi with Wifi capability should work)

- [USB NFC readers](https://www.amazon.com/gp/product/B07Q5KXM6J/ref=ppx_yo_dt_b_asin_title_o06_s00?ie=UTF8&psc=1). These emulate a keyboard -- when an NFC badge is scanned onto them, they 'type' its ID into whatever they're connected to.
- **PLEASE** make note of the model: if that link isn't dead, you'll see it links to a '14H' reader. '14H' (or '14D') is required to get the specificity necessary to distinguish between the NFC badge IDs: these readers read the most significant bit first, and since the card IDs are assigned sequentially this means that most of them have the same first 8-10 hex digits. You are in for much pain if you do not purchase the correct readers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- Microusb battery pack. Best to get flat ones.
- *Optionally*: LEDs

### Hardware: Future Considerations

- Raspberry Pi's are certainly overkill for this application. Since the boxes only need to make a single web request, a simpler IoT board (eg. ESP8266 or ESP32) would work just as well, consume far less power, and cost an order of magnitude less.
- As a corollary, "PiControl" is probably a bad name for this system as pretty much all of the logic is hardware-agnostic. Even the small Python script run on the Pi could probably run on a much simpler microcontroller (with a couple modifications) through Micropython.
- The keyboard emulation NFC readers were used because Katz (the author of this doc) had never touched hardware in his life and thus couldn't figure out how to use the [an actual breakout board](https://www.adafruit.com/product/364). In the first week of CS107e, he realized that he was connecting the board's TX and RX pins to the Pi's TX and RX pins (respectively). He has now learned that TX == "transmit" and RX == "receive" and thus TX on one board should be connected to RX on the other and vice versa. If you ever see Katz, feel free to chastise him for his foolishness.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get it -- are you saying that an actual breakout board would have been a more efficient replacement to the keyboard emulation readers? I haven't touched much hardware before either 😆

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not more efficient per se, but it would've saved us the hassle of requiring all IDs to be unique (and thus having to look around for readers that read the full ID) as we could've added our own IDs or other metadata onto the cards.

Also, this is something of a self-roast as I must've spent 10-15 hours debugging that. I thought it must've been an issue with my code / the dependencies and stupidly didn't consider that I had wired it up wrong.


## Software

### On the Pi

The script run on the Pi can be found at https://github.com/MYKatz/PiControl. If you're using the aforementioned USB NFC readers, you should be running 'read_keyboard.py'.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to just put these files in a scripts subfolder in https://github.com/treehacks/picontrol?


The script is very simple: upon receiving input from the NFC reader (a card's ID), it sends that to a specified API endpoint.

#### OS and dependencies

We used a standard install of Raspbian. You will need to configure the Pi to connect to Wifi -- there are many guides online to do this, such as [this one](https://raspberrypihq.com/how-to-connect-your-raspberry-pi-to-wifi/).

An installation of Python 3.7 should include all of the necessary dependencies except for [Requests](https://requests.readthedocs.io/en/master/). A 'pip3 install requests' should work, provided you're connected to the internet.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, did you want to clarify that you should ssh into the pi and then run pip3 install requests?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a section here about changing the default password for the raspberry pi's?

### Web App

The PiControl web app comprises the vast majority of the logic. You can find it [here](https://github.com/treehacks/picontrol).

PiControl is developed on Postgres, Go (w/ Gin), and React. You can call this the PGRG stack if you hate pronounceable acronyms.

When the script on a Pi is ran for the first time, the Pi is registered with Picontrol and will show up on the 'Pis' page. You can then name the Pi and associate it with an event. When badges are scanned onto the Pi, they'll appear in the logs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to add a screenshot of the pi control web UI right after this paragraph.


#### Eventive Integration

PiControl works by scanning NFC IDs into events on Eventive, which does the heavy lifting matching these IDs to hackers. If you're going to use Eventive (and you probably should, it's great!) then remember to update the EVENTIVE_API_KEY environment variable and change the eventive API link in the code (which is currently hard-coded.. oops!)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you could link to the exact line where the API link is hard coded, that would be great.


#### Environment Variables

```
DATABASE_URL= /* postgresql uri string */
EVENTIVE_API_KEY=
GIN_MODE=release /* either 'debug' or 'release' */
PASSWORD=

```

#### Development Set-up

- Set "homepage" in package.json to the url you want.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What URL should this be set to? Why does it need to be set?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was horrible in not specifying. This sets the root url of the frontend to be whatever "homepage" is, but I don't think that's necessary to include in the documentation, as it should be "/admin" in order for everything to work anyway. Will remove

- Run `go get -u github.com/gin-gonic/gin github.com/joho/godotenv github.com/lib/pq`
- Run `npm run dev-start`

Pushing and pulling to docker: https://ropenscilabs.github.io/r-docker-tutorial/04-Dockerhub.html
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to push and pull to docker, though, right? It's just enough to build the docker image locally (i.e. the steps mentioned in the "Installation" section next)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had previously used docker cloud in deployments, but yeah this is no longer necessary and may lead to confusion. Good catch, removing


#### Installation

- Build using the dockerfile
- Get the build onto your server
- create .env file
- $ sudo docker run -d -t --env-file=".env" -p 80:80 [container id]
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ nav:
- Cog: cog.md
- Gavel: gavel.md
- Submit: submit.md
- PiControl: picontrol.md
- DevOps:
DNS: devops/dns.md
AWS Inventory: devops/aws-inventory.md
Expand Down