# Hardware Integration Spec: NFC, QR Codes & E-Ink Displays
## 🔖 NFC/RFID Integration
### Use Cases
1. **Visitor Badge Scan**: Tap badge to check in/out
2. **Employee Time Clock**: Tap badge to clock in/out
3. **Zone Access**: Tap to log entry into restricted areas
4. **Equipment Checkout**: Tap to log tool/equipment usage
5. **Plant/Batch Tags**: Tap to view batch details on mobile
### Hardware Options
| Device Type | Range | Use Case | Est. Cost |
|-------------|-------|----------|-----------|
| **MIFARE DESFire EV3** | 3-5cm | High-security badges | $2-5/card |
| **NFC Tags (NTAG216)** | 1-3cm | Plant/room tags | $0.20-0.50/tag |
| **USB NFC Reader** | 3-5cm | Desktop check-in | $30-50 |
| **Embedded NFC (Phone)** | 1-5cm | Mobile scan | Built-in |
### Data Model
```prisma
model NFCTag {
id String @id @default(uuid())
uid String @unique // NFC chip unique ID
type String // BADGE, PLANT_TAG, ROOM_TAG, EQUIPMENT
linkedId String // Points to User, Batch, Room, or Equipment
linkedType String // USER, BATCH, ROOM, EQUIPMENT
isActive Boolean @default(true)
createdAt DateTime @default(now())
}
model NFCScan {
id String @id @default(uuid())
tagId String
scannedBy String? // User who scanned
deviceId String? // Which reader/phone
action String // CHECK_IN, CHECK_OUT, VIEW, ACCESS
location String?
timestamp DateTime @default(now())
}
```
### API Endpoints
```
POST /api/nfc/scan
Body: { uid, deviceId, location }
Returns: { action, linkedEntity, redirect? }
POST /api/nfc/provision
Body: { uid, type, linkedId }
Returns: { tagId, success }
GET /api/nfc/tag/:uid
Returns: Tag details + linked entity
```
### Frontend Integration
```tsx
// Using Web NFC API (Chrome Android only currently)
if ('NDEFReader' in window) {
const reader = new NDEFReader();
await reader.scan();
reader.onreading = (event) => {
const uid = event.serialNumber;
await api.post('/nfc/scan', { uid, deviceId: getDeviceId() });
};
}
```
---
## 📱 QR Code System
### Use Cases
1. **Batch QR**: Scan to view batch details, log touch points
2. **Room QR**: Posted at room entrance, shows room status
3. **Visitor Badge**: QR code printed on visitor badges
4. **Equipment Tags**: Scan to view maintenance history
5. **SOP Access**: Scan to view relevant procedures
### QR Code Content Format
```json
{
"v": 1, // Version
"t": "BATCH", // Type
"id": "abc123", // Entity ID
"u": "https://app.777wolfpack.com/batch/abc123"
}
```
### Generation & Display
```tsx
// Using qrcode.react
import { QRCodeSVG } from 'qrcode.react';
```
### Scanning
- **Mobile App**: Use device camera + library like `@zxing/browser`
- **Kiosk**: USB camera with continuous scanning
- **Web**: `navigator.mediaDevices.getUserMedia()` + `jsQR`
### Printable Labels
- **Batch Labels**: 2x1" thermal labels with QR + batch name
- **Room Signs**: 4x6" laminated signs with room QR
- **Visitor Badges**: 3x4" sticky label printer
---
## 📺 E-Ink Display Network
### Vision
Mount low-power e-ink displays throughout the facility showing real-time room status, tasks, and alerts. Zero maintenance (battery lasts 2+ years).
### Hardware Recommendations
| Device | Display | Battery | WiFi | Est. Cost | Use Case |
|--------|---------|---------|------|-----------|----------|
| **Waveshare 7.5" e-Paper** | 800x480 | 6-12 mo | ESP32 | $45 | Room status boards |
| **LILYGO T5** | 2.13" | 12+ mo | ESP32 | $20 | Shelf tags |
| **Good Display 4.2"** | 400x300 | 12+ mo | ESP32 | $35 | Plant row tags |
| **Inkplate 6** | 6" | 12+ mo | ESP32 | $80 | Task boards |
### Display Locations & Content
#### 1. Room Entrance Displays (7.5")
```
┌────────────────────────────────┐
│ 🌿 ROOM: VEG-A │
│ ─────────────────────────────│
│ Batches: 4 │
│ Plants: 847 │
│ Stage: Vegetative │
│ ─────────────────────────────│
│ CURRENT TASKS: │
│ □ Water all trays (Due 2pm) │
│ □ Trim lower fan leaves │
│ ─────────────────────────────│
│ Last updated: Dec 10, 2:30pm │
│ [QR CODE] Scan for details │
└────────────────────────────────┘
```
#### 2. Batch Row Tags (2.13")
```
┌──────────────┐
│ BATCH: OGK-4 │
│ Plants: 48 │
│ Day 24 / Veg │
│ [QR] │
└──────────────┘
```
#### 3. Task Board (6")
```
┌────────────────────────────────┐
│ 📋 TODAY'S TASKS │
│ ─────────────────────────────│
│ OVERDUE (2) │
│ • IPM spray - Flower-B │
│ • Transplant clones │
│ ─────────────────────────────│
│ DUE TODAY (5) │
│ □ Morning inspection │
│ □ Water schedule - All rooms │
│ □ Foliar feed - Veg rooms │
│ □ Trim - Flower-A │
│ □ Harvest prep - Dry room │
│ ─────────────────────────────│
│ Shift: Day | Staff: 4 active │
└────────────────────────────────┘
```
### Architecture
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Backend │────▶ │ Redis/ │────▶ │ Display │
│ API │ │ MQTT │ │ Controller │
└─────────────┘ └─────────────┘ └─────────────┘
│
┌───────────────────────────┼───────────────────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ Room-A │ │ Room-B │ │ Lobby │
│ E-Ink │ │ E-Ink │ │ E-Ink │
└─────────────┘ └─────────────┘ └─────────────┘
```
### Update Protocol
1. **Backend publishes** status change to MQTT topic `display/room/{roomId}`
2. **ESP32 subscribes** to its topic, wakes on message
3. **ESP32 fetches** image from `GET /api/display/room/{roomId}?format=bmp`
4. **Backend renders** server-side image (using Puppeteer or Sharp)
5. **ESP32 displays** image and goes back to deep sleep
### API Endpoints
```
GET /api/display/room/:id
Returns: BMP/PNG image optimized for e-ink
GET /api/display/tasks
Query: ?type=overview|room
Returns: Task board image
POST /api/display/register
Body: { deviceId, type, linkedId }
Returns: { displayId, config }
```
### Power Management
- **Deep Sleep**: ESP32 sleeps 90%+ of time
- **Wake Schedule**: Every 15 min OR on MQTT push
- **Battery Monitor**: Report battery level with each update
- **Solar Option**: Some displays have solar panels (2+ years)
### Firmware (ESP32 Arduino)
```cpp
#include
#include
#include
void loop() {
connectWiFi();
HTTPClient http;
http.begin("https://api.777wolfpack.com/display/room/veg-a?format=bmp");
http.addHeader("Authorization", "Bearer " + String(API_KEY));
int httpCode = http.GET();
if (httpCode == 200) {
// Stream directly to display
display.drawBitmap(http.getStream());
}
http.end();
WiFi.disconnect();
// Sleep for 15 minutes
esp_deep_sleep(15 * 60 * 1000000);
}
```
---
## 📊 Implementation Priority
| Feature | Priority | Effort | Impact |
|---------|----------|--------|--------|
| QR Code generation | 🔴 High | 1 day | Immediate utility |
| Batch QR labels | 🔴 High | 2 days | Track & trace |
| Visitor badge QR | 🔴 High | 1 day | Compliance |
| Room entrance e-ink | 🟡 Medium | 1 week | Visibility |
| NFC badge check-in | 🟡 Medium | 3 days | Efficiency |
| Batch row e-ink tags | 🟢 Low | 2 weeks | Nice to have |
---
## 🔧 Quick Wins (Start Here)
1. **Add QR codes to batch cards** - Use `qrcode.react`
2. **Print batch labels** - Thermal printer + QR
3. **Visitor badge printing** - Generate PDF with QR
4. **One pilot e-ink display** - Room entrance PoC