Python 3 library for interacting with Pitboss grills and smokers.
Note that this project has no official relationship with Pitboss or Danson's. Use at your own risk.
pytboss supports three ways of talking to a grill: a direct Bluetooth LE
connection, a WebSocket connection to the PitBoss cloud service, or an HTTP
connection to the grill on your own network. All three use the same PitBoss
API once connected — only the Transport passed to it differs.
If you don't already know your grill's Bluetooth address, you can discover
nearby devices with bleak:
import asyncio
from bleak import BleakScanner
async def discover():
devices = await BleakScanner.discover()
for device in devices:
print(device.address, device.name)
asyncio.run(discover())Once you have the address, connect and subscribe to state updates:
import asyncio
from bleak import BleakScanner
from pytboss import BleConnection, PitBoss
async def state_callback(data):
print(data)
async def main():
device_address = "AA:BB:CC:DD:EE:FF" # Your grill's Bluetooth address.
ble_device = await BleakScanner.find_device_by_address(device_address)
model = "PBV4PS2" # Or your model. See below.
boss = PitBoss(BleConnection(ble_device), model)
# Subscribe to updates from the smoker.
await boss.subscribe_state(state_callback)
await boss.start()
while True:
await asyncio.sleep(0.1)
asyncio.run(main())The WebSocket transport talks to the PitBoss cloud service instead of
connecting directly over Bluetooth, which is useful when the grill isn't in
Bluetooth range. It requires the grill's unique identifier (grill_id),
which you can find in the PitBoss mobile app or account settings; this
library does not currently provide a way to look it up.
import asyncio
from pytboss import PitBoss, WebSocketConnection
async def state_callback(data):
print(data)
async def main():
grill_id = "your-grill-id"
model = "PBV4PS2" # Or your model. See below.
boss = PitBoss(WebSocketConnection(grill_id), model)
await boss.subscribe_state(state_callback)
await boss.start()
while True:
await asyncio.sleep(0.1)
asyncio.run(main())Mongoose OS serves the same RPC interface at http://<grill-ip>/rpc that the
Dansons relay forwards, so this transport talks to the grill directly, with
the vendor's cloud out of the path.
Not every grill answers. The ESP-IDF firmware line (versioned 16.x, on
the PBC2, PBD, PBE, PBL2 and PBT boards) links no HTTP server at all, and
Mongoose grills serve the endpoint only when http.enable is set — per-unit
configuration that no model or firmware version predicts. Nothing in this
library turns it on; connect() simply fails. Check first over a transport
that already works:
from pytboss.exceptions import RPCError
try:
http = await boss.config.get_config("http")
except RPCError:
http = {} # No such section: not a Mongoose grill.
if http.get("enable"):
... # An HttpConnection will work against this grill.There is no push channel. HTTP is strictly request/response, so unlike the
other two transports this one never invokes the state or VData callbacks —
subscribe_state() registers a callback that will not fire. Poll
get_state() instead; it issues a live RPC and updates the same cache the
rest of the API reads.
import asyncio
from pytboss import HttpConnection, PitBoss
async def main():
host = "192.168.1.50" # Your grill's address on the network.
model = "PBV4PS2" # Or your model. See below.
boss = PitBoss(HttpConnection(host), model)
await boss.start()
while True:
print(await boss.get_state())
await asyncio.sleep(10)
asyncio.run(main())Calls to the grill can fail for a number of reasons — the grill may be
unreachable, the connection may drop, or an RPC may be rejected. These are
all raised as subclasses of pytboss.exceptions.Error:
from pytboss.exceptions import Error, GrillUnavailable, InvalidGrill, NotConnectedError
try:
boss = PitBoss(WebSocketConnection(grill_id), model)
await boss.start()
except InvalidGrill:
print(f"Unknown grill model: {model}")
except GrillUnavailable:
print("Could not reach the grill.")
except NotConnectedError:
print("Not connected to the grill.")
except Error as ex:
print(f"Unexpected error: {ex}")pytboss requires Python 3.12 or later.
To install pytboss, run this command in your terminal:
$ pip install pytbossPytboss is actively developed on Github, where the code is always available.
You can either clone the public repository:
$ git clone https://github.com/dknowles2/pytbossOr download the latest tarball:
$ curl -OL https://github.com/dknowles2/pytboss/tarball/mainOnce you have a copy of the source, you can embed it in your own Python package, or install it into your site-packages easily:
$ cd pytboss
$ python -m pip install .The following models should be supported. Note however that only the PBV4PS2 model has been tested.
- LG0800BL
- LG1000BL
- LG1200BL
- LG1200FL
- LG1200FP
- LG300BL
- LG800FL
- LG800FP
- LGV4BL
- Lexington Wi-Fi Upgrade
- PB0500SP
- PB0820SP/SPW
- PB1000D3
- PB1000NC1
- PB1000NXW
- PB1000PL
- PB1000R1
- PB1000R2
- PB1000S1
- PB1000SC1
- PB1000SC2
- PB1000SP
- PB1000T1
- PB1000T2
- PB1000T3
- PB1000T4
- PB1000XL/PB1000SC3
- PB1000XLW1 (Austin XL)
- PB1020CS2
- PB1020DX
- PB1020NXW
- PB1100HTC
- PB1100PS1
- PB1100PSC1
- PB1100PSC2
- PB1100PSC3
- PB1100SP/SPW
- PB1100SPW2
- PB1150 PS3
- PB1150DX
- PB1150G/GW
- PB1150PS2
- PB1150PS3
- PB1230
- PB1230CS1
- PB1230G/GW
- PB1230SP/SPW
- PB1250 CS2
- PB1250 NX
- PB1250 PL
- PB1250CS
- PB1250CS2
- PB1250NX
- PB1250PL
- PB1285KC
- PB1285PC
- PB1300 M
- PB1300 PS4
- PB1300M
- PB1300PS4
- PB1450CS
- PB1500NXW
- PB1600 CS
- PB1600 CS2
- PB1600 M
- PB1600 PSE
- PB1600AMB
- PB1600CS
- PB1600CS2
- PB1600CST
- PB1600M
- PB1600PS1
- PB1600PS2
- PB1600PS3
- PB1600PS3_
- PB1600PS4
- PB1600PSE
- PB1600SPW
- PB1600SPW2
- PB2180LK
- PB340
- PB340TGW1 (Tailgator)
- PB440D
- PB440D2
- PB440D3/PB456D
- PB440TG1
- PB440TGNC1
- PB440TGR1
- PB550G
- PB700D
- PB700FB
- PB700FBM2
- PB700FBW2 (Classic)
- PB700NC1
- PB700R1
- PB700R2
- PB700S
- PB700S1
- PB700S2
- PB700SC
- PB700T1
- PB820CS1
- PB820D
- PB820D2
- PB820D3
- PB820D4
- PB820FB
- PB820FBC
- PB820PS1
- PB820S
- PB820SC
- PB820T1
- PB820XL/PB820ME
- PB850AMB
- PB850CS1
- PB850CS2
- PB850DX
- PB850G/GW
- PB850M
- PB850PS2
- PB850SPW2
- PBV3 M
- PBV3M
- PBV3NX
- PBV4DX
- PBV4NXW
- PBV4PS2
- PBV5 P2
- PBV5CS
- PBV5P2
- PBV5PL
- PBV6 M
- PBV6 PSE
- PBV6M
- PBV6PSE
- PBV7P2
- PBV7PW1
To work on pytboss itself, install uv and
sync the test dependencies (uv manages the Python 3.12+ interpreter and
virtual environment for you):
$ uv sync --group testRun the test suite, linter, and type checker:
$ uv run pytest
$ uv run ruff check .
$ uv run mypy .pre-commit hooks are also available; sync the
dev group and install them with:
$ uv sync --group dev
$ uv run pre-commit install