Skip to content

Getting Started

Installation

pip install python-bsblan

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.

import os

config = BSBLANConfig(
    host=os.getenv("BSBLAN_HOST", "192.168.1.100"),
    username=os.getenv("BSBLAN_USERNAME"),
    password=os.getenv("BSBLAN_PASSWORD"),
)

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() for hvac_mode, target_temperature, and current_temperature
  • static_values() for min_temp and max_temp
  • thermostat() for target temperature and HVAC mode
  • get_available_circuits(), which returns [1] when the single PPS climate circuit is available, otherwise []; PPS devices only ever expose circuit 1

PPS devices currently have these limitations:

  • Only circuit 1 is supported.
  • time() and set_time() are not supported for PPS devices.
  • thermostat(hvac_mode=2) is not supported on PPS devices. Valid PPS modes are 0 (off), 1 (auto), and 3 (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))

Multi-circuit support

async with BSBLAN(config) as client:
    # Get available heating circuits
    circuits = await client.get_available_circuits()
    print(f"Available circuits: {circuits}")

    # Read state for a specific circuit
    state = await client.state(circuit=2)