Getting Started¶
Installation¶
Configuration¶
Create a BSBLANConfig object with your device connection details:
from bsblan import BSBLAN, BSBLANConfig
config = BSBLANConfig(
host="192.168.1.100",
passkey=None, # Set if your device uses passkey auth
username=None, # Set for username/password auth
password=None,
)
Security
Never hard-code credentials in your source code. Use environment variables or a secrets manager instead.
Basic usage¶
import asyncio
from bsblan import BSBLAN, BSBLANConfig
async def main() -> None:
config = BSBLANConfig(host="192.168.1.100")
async with BSBLAN(config) as client:
# Read current heating state
state = await client.state()
print(f"HVAC Mode: {state.hvac_mode.desc}")
print(f"Current Temp: {state.current_temperature.value}")
# Read sensor data
sensor = await client.sensor()
print(f"Outside Temp: {sensor.outside_temperature.value}")
# Set thermostat
await client.thermostat(target_temperature="21.5")
# Get device info
device = await client.device()
print(f"Device: {device.name} v{device.version}")
asyncio.run(main())
Firmware compatibility¶
On the first request the client lazily runs initialize(), which detects the
device's capabilities and selects a matching configuration based on the BSB-LAN
JSON-API version reported by the /JV endpoint:
- Full configuration — JSON-API version 2.0 or newer. All features are available, including multiple heating circuits, hot water control, schedules, sensors, and cooling setpoints.
- Basic configuration — JSON-API version 1.x. A reduced, single-circuit configuration covering essential heating, hot water, and sensor parameters.
The JSON-API version is the documented, firmware-independent compatibility
signal. The adapter firmware version (from /JI) is still retrieved and exposed
via device_info, but it is not used to determine support. A device that does
not expose /JV, or reports a JSON-API version below 1.0, raises
BSBLANVersionError.
Basic (JSON-API 1.x) support is best-effort and may not cover every parameter your heating system exposes.
Temperature bounds¶
For heating comfort setpoint writes (target_temperature), the lower bound is
the protective (frost) setpoint (714 for circuit 1, 1014 for circuit 2),
which allows setpoints down to the frost-protection temperature. The reduced
setpoint (712/1012) is exposed as min_temp for reference and is used as a
fallback lower bound only when the protective setpoint is unavailable (for
example, on PPS devices). The upper heating bound is the comfort maximum (716
for circuit 1 and 1016 for circuit 2) when the device exposes those
parameters.
Cooling setpoint support¶
Some BSB/LPB controllers expose a cooling comfort setpoint for each heating
circuit. The client maps BSB-LAN parameter 902 for circuit 1 and 1202 for
circuit 2 to target_temperature_high; the duplicate decimal parameters
902.1 and 902.2 are not used.
When available, cooling setpoint validation uses 905/1205 (comfort setpoint
minimum) as the lower bound and 903/1203 (room temperature reduced setpoint)
as the upper bound. Parameters 908 and 1208 are flow setpoints and are not
used for room setpoint validation.
Cooling support is optional. During section validation, unsupported parameters
are removed from the active API map, so integrations can detect support by
checking whether state.target_temperature_high is present.
async with BSBLAN(config) as client:
state = await client.state(include=["target_temperature_high"])
if state.target_temperature_high is not None:
print(f"Cooling setpoint: {state.target_temperature_high.value}")
await client.thermostat(target_temperature_high="24.0")
BSB-LAN writes one parameter at a time. If an application exposes a heat/cool
temperature range, write target_temperature and target_temperature_high with
separate thermostat() calls.
Cooling operating mode¶
The cooling circuit has its own operating mode, separate from the heating
hvac_mode (700/1000) and the read-only changeover status (900/1200).
The client maps BSB-LAN parameter 901 for circuit 1 and 1201 for circuit 2
to cooling_operating_mode. Valid values are 0 (Protection), 1
(Automatic), 2 (Reduced), and 3 (Comfort).
Like the cooling setpoint, the parameter is optional and removed from the
active API map when the device does not expose it, so integrations can detect
support by checking whether state.cooling_operating_mode is present.
async with BSBLAN(config) as client:
state = await client.state(include=["hvac_mode", "cooling_operating_mode"])
if state.cooling_operating_mode is not None:
print(f"Cooling mode: {state.cooling_operating_mode.desc}")
await client.thermostat(cooling_operating_mode=1)
Setting cooling_operating_mode is not supported on PPS devices.
PPS bus support¶
PPS bus devices are detected from the device metadata returned by BSB-LAN. The client provides minimal climate support for PPS devices through the same climate methods used by BSB/LPB devices.
Supported PPS climate operations:
state()forhvac_mode,target_temperature, andcurrent_temperaturestatic_values()formin_tempandmax_tempthermostat()for target temperature and HVAC modeget_available_circuits(), which returns[1]when the single PPS climate circuit is available, otherwise[]; PPS devices only ever expose circuit1
PPS devices currently have these limitations:
- Only circuit
1is supported. time()andset_time()are not supported for PPS devices.thermostat(hvac_mode=2)is not supported on PPS devices. Valid PPS modes are0(off),1(auto), and3(heat/manual).- Hot water and schedule helpers are intended for BSB/LPB devices.
Check supports_time_sync before showing or calling time synchronization in
applications:
async with BSBLAN(config) as client:
device = client.device_info or await client.device()
print(f"Bus type: {device.bus or 'unknown'}")
if client.supports_time_sync:
device_time = await client.time()
print(device_time.time.value)
Hot water control¶
from bsblan import SetHotWaterParam
async with BSBLAN(config) as client:
# Read hot water state
hw_state = await client.hot_water_state()
print(f"DHW Mode: {hw_state.operating_mode.desc}")
# Read hot water configuration
hw_config = await client.hot_water_config()
# Set hot water temperature
await client.set_hot_water(SetHotWaterParam(nominal_setpoint=55.0))