pepper_c1 v0.1.4

Python driver for the Eccel Peeper C1 NFC/RFID reader — communicates over UART or TCP using a custom binary framing protocol.

Installation

# From PyPI
pip install pepper_c1

# From source, with development dependencies
pip install -e ".[dev]"

Quick Start

Connect a reader to a serial port or TCP socket, then use the PepperC1 client as a context manager:

from pepper_c1 import PepperC1, UARTTransport, TCPTransport

# UART connection
with PepperC1(UARTTransport('COM3')) as reader:
    print(reader.get_version())
    uid_info = reader.get_uid()
    print(uid_info[2:].hex())   # bytes after type+param

# TCP connection
with PepperC1(TCPTransport('192.168.1.100', 1234)) as reader:
    print(reader.get_version())

Supported Tag Families

MIFARE Classic
1K / 4K / Mini — block read/write, value blocks, key authentication
MIFARE Ultralight
Ultralight / Ultralight-C / EV1 — page operations, NFC counter, password auth
MIFARE DESFire
EV1/EV2 — app management, data/value/record files, transactions, AES auth
ICODE
SLI / SLIX / SLIX2 / DNA — block operations, system information, security

Transport Options

UARTTransport
Serial communication via pyserial — COM port or /dev/ttyUSBx
TCPTransport
TCP socket — connect to reader over Ethernet / Wi-Fi

Tag Type Identifiers

The first byte of the get_uid() response payload identifies the tag type:

Type byteTag family
0x01MIFARE Ultralight
0x02MIFARE Ultralight-C
0x03MIFARE Classic
0x04MIFARE Classic 1K
0x05MIFARE Classic 4K
0x06MIFARE Plus
0x07MIFARE Plus 2K
0x08MIFARE Plus 4K
0x09MIFARE Plus 2K SL2
0x0AMIFARE Plus 4K SL2
0x0BMIFARE Plus 2K SL3
0x0CMIFARE Plus 4K SL3
0x0DMIFARE DESFire
0x0FJCOP
0x10MIFARE Mini
0x21ICODE SLI
0x22ICODE SLI-S
0x23ICODE SLI-L
0x24ICODE SLIX
0x25ICODE SLIX-S
0x26ICODE SLIX-X
0x27ICODE SLIX2
0x28ICODE DNA

Error Handling

from pepper_c1 import PepperC1, UARTTransport, CommandError, TransportError

try:
    with PepperC1(UARTTransport('COM3')) as reader:
        reader.mf_read_block(5)
except TransportError as e:
    print(f"Connection failed: {e}")
except CommandError as e:
    print(f"Device error on cmd 0x{e.cmd:02X}: code 0x{e.error_code:04X}")
except TimeoutError:
    print("No response from reader")

Package Layout

pepper_c1/
├── __init__.py      — public exports
├── commands.py      — Command enum + KEY_TYPE_* constants
├── exceptions.py    — ProtocolError, TransportError, CommandError
├── protocol.py      — calc_crc, build_frame, parse_frame, FrameParser
├── transport.py     — Transport (ABC), UARTTransport, TCPTransport
└── client.py        — PepperC1 main client class
tests/
├── test_protocol.py
└── test_client.py
tools/               ← example scripts
├── read_uid.py
├── mifare_classic.py
├── mifare_ultralight.py
├── desfire.py
├── icode.py
├── example_client.py
└── mux_example.py