Skip to main content

Baltech SDK

Installation

pip install baltech-sdk

Usage

from baltech_sdk import Brp, UsbHid

# Sample code for GetInfo
with Brp(UsbHid()) as brp:
    print(brp.Sys_GetInfo())

# This is a shortcut for:
io = UsbHid()
brp = Brp(io, open=False)
brp.open()
print(brp.Sys_GetInfo())
brp.close()

A complete reference of the supported commands can be found here.

Supported IO protocols

from baltech_sdk import Brp, UsbHid, RS232

# USB HID autodetect connected reader
brp = Brp(UsbHid())

# USB HID by serialnumber
brp = Brp(UsbHid(serialnumber=99999999))

# Serial with (optional) custom settings
brp = Brp(RS232("COM1", baudrate=115200, parity=b"N"))

Reader Update

from baltech_sdk import Brp, UsbHid, ReaderUpdater

with Brp(UsbHid(), open=True) as brp:
    updater = ReaderUpdater.from_path("firmware.bf3")

    # simple upload
    updater.run(brp)

    # upload with progress
    for progress in updater.iter(brp):
        print(f"{progress.progress:.0%} ({progress.transferred_bytes} bytes)")

Access Reader Configuration

from baltech_sdk import Config

cfg_src = {(0x0201, 0x02): b'\x01'}   # instead of a confDict also a brp object 
                                     # can be passed to modify reader's 
                                     # configuration directly
cfg = Config(cfg_src)

# set value
cfg.Device_Boot_StartAutoreadAtPowerup("EnableOnce")

# get value
print(cfg.Device_Boot_StartAutoreadAtPowerup.get())

# delete value
cfg.Device_Boot_StartAutoreadAtPowerup.delete()

Templates and BaltechScripts

from baltech_sdk import Config, Template, BaltechScript, TemplateFilter

confdict = {}
cfg = Config(confdict)

cfg.Scripts_Events_OnAccepted(
    BaltechScript()
        .ToggleInverted("RedLed", RepeatCount=3, Delay=20)
        .Toggle("GreenLed", RepeatCount=1, Delay=20)
        .DefaultAction()
)
cfg.Autoread_Rule_Template(
    0, 
    Template()
        .Static(b"SNR:")
        .Serialnr(TemplateFilter(BinToAscii=True, Unpack=True, BinToBcd=True))
)
print(confdict)

Linux or macOS

To use baltech-sdk under Linux or macOS you need to build your own binary of the BaltechSDK and manually set the path to your binary.

from pathlib import Path
from baltech_sdk import set_brp_lib_path

set_brp_lib_path(Path("path/to/brp_lib"))

Custom protocols

Implement your own protocol in Python by subclassing CustomProtocol. Override only the methods you need; not overriding a method makes it a transparent passthrough to the layer below. Add the role marker (IoProtocol / CryptoProtocol) matching where the protocol is meant to be mounted.

A byte-stream I/O transport (here over a TCP socket) overrides send_frame and recv_frame. recv_frame drives the framing loop: missing_bytes_cb(chunk) appends chunk and returns how many bytes are still missing (0 = frame complete):

import socket
from baltech_sdk import Brp, CustomProtocol, IoProtocol
from brp_lib.err import BrpTimeoutError

class TcpIo(CustomProtocol, IoProtocol):
    INTERFACE_NAME = "IP"                      # log filename "{interface}-{instance}.html"

    def __init__(self, host, port):
        super().__init__()
        self.host, self.port = host, port

    @property
    def instance_id(self):                     # the "{instance}" half (e.g. "IP-192.168.0.42.html")
        return self.host

    def open(self):
        super().open()
        self.sock = socket.create_connection((self.host, self.port), timeout=5)

    def close(self):
        self.sock.close()
        super().close()

    def send_frame(self, data):
        self.sock.sendall(data)

    def recv_frame(self, timeout, missing_bytes_cb):
        self.sock.settimeout(None if timeout is None else timeout / 1000)
        chunk = b""
        while True:
            n = missing_bytes_cb(chunk)       # bytes still missing (0 = complete)
            if n == 0:
                break
            try:
                chunk = self.sock.recv(n)
            except (socket.timeout, TimeoutError):
                raise BrpTimeoutError()
            if not chunk:
                raise BrpTimeoutError()

with Brp(TcpIo("192.168.0.42", 9999)) as brp:
    print(brp.Sys_GetInfo())

(A message/datagram transport that reads whole frames overrides recv_any_frame(timeout) instead of recv_frame.)

A middle layer transforms whole frames and forwards them to the layer below via self.base (here a toy obfuscation in the crypto slot). It can also run a handshake when the stack is opened by extending open: super().open() brings up the layer below, then exchange frames over it; raise a BrpError to abort (the stack stays closed):

from baltech_sdk import Brp, UsbHid, CustomProtocol, CryptoProtocol, Layer
from brp_lib.err import OpenIOError

class XorLayer(CustomProtocol, CryptoProtocol):
    def open(self):
        super().open()                            # opens the layer below first
        self.base.send_frame(b"AUTH-REQ")          # negotiated in clear (no XOR)
        if self.base.recv_any_frame(2000) != b"AUTH-OK":
            raise OpenIOError("handshake rejected")

    def send_frame(self, data):
        self.base.send_frame(bytes(b ^ 0x5A for b in data))

    def recv_any_frame(self, timeout=None):
        return bytes(b ^ 0x5A for b in self.base.recv_any_frame(timeout))

brp = Brp(UsbHid())
brp.set_layer(Layer.CRYPTO, XorLayer())
brp.open()                                    # runs XorLayer.open()

For open/close, extend with super() as usual — like every implementor of an open callback (in C too), an override is responsible for bringing up the layer below itself, and super().open() does exactly that (forget it and the handshake send_frame fails on the still-closed base). For data methods, forward through self.base, never super() — their base implementations are "not implemented" markers, the layer below is reached via base. self.base.send_frame / self.base.recv_any_frame exchange raw frames with the layer directly below. For high-level command negotiation (e.g. brp.Sys_GetInfo()), run it after brp.open() — those calls need the BRP framing layer above this one.

Further parameters on connections fors sensible data

Additional Options:

from baltech_sdk import Brp, UsbHid, SecureChannel

KEY = b'abcdefghijklmnuk'
brp = Brp(UsbHid(), 
          crypto=SecureChannel(security_level=1, key=KEY),  # encrypt communication
          monitor="plaintext"                               # log unencrypted data (if activated by user)
)

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

baltech_sdk-5.2026.8.tar.gz (298.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

baltech_sdk-5.2026.8-py3-none-any.whl (303.4 kB view details)

Uploaded Python 3

File details

Details for the file baltech_sdk-5.2026.8.tar.gz.

File metadata

  • Download URL: baltech_sdk-5.2026.8.tar.gz
  • Upload date:
  • Size: 298.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for baltech_sdk-5.2026.8.tar.gz
Algorithm Hash digest
SHA256 2072e419478dec991362e3e8fada7f6b1613301c69db4b4d614108d0136aa280
MD5 7c6389ac25044bbef4f5fa02f2a822c1
BLAKE2b-256 5fce655efd9bd77c5cbcbc1b188f6d6ddbf05d30f60348ad0a73d7be295b3005

See more details on using hashes here.

File details

Details for the file baltech_sdk-5.2026.8-py3-none-any.whl.

File metadata

  • Download URL: baltech_sdk-5.2026.8-py3-none-any.whl
  • Upload date:
  • Size: 303.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for baltech_sdk-5.2026.8-py3-none-any.whl
Algorithm Hash digest
SHA256 b94a9565857b23c07f850fa664730f831786a206deece1ef8efefc00781a83e6
MD5 13f025b493eb20d0f3978f8476a23722
BLAKE2b-256 7cd7833117cc9d91070c88837af95fa89d0165886ffb2a9df323639e7e91411e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

5.2026.8 This release

2 files

5.2026.7

2 files

5.2026.6.1

2 files

5.2026.6

2 files

5.2026.5

2 files

5.2026.4

2 files

5.2026.3.1

2 files

4.2026.3

2 files

4.2026.2.2

2 files

3.19.4

2 files

3.19.3

1 file

3.19.2

1 file

3.19.1

1 file

3.19.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page