Python library for accessing SensorLinx Device Data
Project description
pysensorlinx
An async Python library for the SensorLinx API. It provides full control of HBX HVAC controllers (such as the ECO-0600) — reading sensor data, getting and setting device parameters, and managing heat-pump staging, tank temperatures, backup settings, and more.
Features
- Async — built on
aiohttpfor non-blocking I/O - Login & session management — authenticate, auto-refresh tokens, and close sessions
- Buildings & devices — list buildings and enumerate devices per building
- Get & set parameters — read and write every ECO-0600 configuration parameter
- Temperature objects —
TemperatureandTemperatureDeltaclasses with automatic °F ↔ °C conversion - Read sensor data — retrieve live temperature sensor readings and stage runtimes
- Exception hierarchy — typed exceptions for login failures and invalid parameters
Installation
pip install pysensorlinx
Development install
git clone https://github.com/sslivins/pysensorlinx.git
cd pysensorlinx
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
pip install -e .[tests]
Quick start
import asyncio
from pysensorlinx import Sensorlinx, SensorlinxDevice
async def main():
api = Sensorlinx()
try:
await api.login("your_username", "your_password")
# List buildings
buildings = await api.get_buildings()
building_id = buildings[0]["_id"]
# List devices in the first building
devices = await api.get_devices(building_id)
device_id = devices[0]["syncCode"]
# Create a device helper
device = SensorlinxDevice(api, building_id, device_id)
# Read parameters
mode = await device.get_hvac_mode_priority() # "heat", "cool", or "auto"
temps = await device.get_temperatures() # dict of sensor readings
max_temp = await device.get_hot_tank_max_temp() # Temperature(150.00, 'F')
# Write parameters
await device.set_hvac_mode_priority("auto")
await device.set_hot_tank_max_temp(160) # accepts int (°F) or Temperature
finally:
await api.close()
asyncio.run(main())
Temperature & TemperatureDelta
The library returns temperature values as Temperature or TemperatureDelta objects that handle unit conversion automatically. The API stores all values in °F.
from pysensorlinx import Temperature, TemperatureDelta
# Absolute temperatures (°F = °C × 9/5 + 32)
t = Temperature(212, "F")
print(t.to_celsius()) # 100.0
print(t.as_celsius()) # Temperature(100.00, 'C')
print(t) # 212.00°F
# Temperature differentials (ΔF = ΔC × 9/5, no +32 offset)
d = TemperatureDelta(9, "F")
print(d.to_celsius()) # 5.0
print(d.as_celsius()) # TemperatureDelta(5.00, 'C')
print(d) # 9.00Δ°F
Temperature methods
| Method | Returns | Description |
|---|---|---|
to_celsius() |
float |
Value converted to °C |
to_fahrenheit() |
float |
Value converted to °F |
as_celsius() |
Temperature |
New Temperature object in °C |
as_fahrenheit() |
Temperature |
New Temperature object in °F |
TemperatureDelta has the same methods (returns TemperatureDelta for as_*).
Some getters return 'off' when the feature is disabled:
shutdown = await device.get_warm_weather_shutdown() # Temperature(75.00, 'F') or 'off'
API reference
Sensorlinx
The low-level API client. Manages authentication and HTTP requests.
| Method | Description |
|---|---|
login(username, password) |
Authenticate with SensorLinx |
close() |
Close the HTTP session |
get_profile() |
Fetch the authenticated user's profile |
get_buildings(building_id=None) |
List all buildings, or fetch one by ID |
get_devices(building_id, device_id=None) |
List devices in a building, or fetch one |
set_device_parameter(building_id, device_id, **kwargs) |
Set one or more device parameters |
SensorlinxDevice
A high-level wrapper around a single device. All methods are async.
Getters
| Method | Returns | Notes |
|---|---|---|
get_hvac_mode_priority() |
str |
"heat", "cool", or "auto" |
get_permanent_heat_demand() |
bool |
|
get_permanent_cool_demand() |
bool |
|
get_weather_shutdown_lag_time() |
int |
hours |
get_heat_cool_switch_delay() |
int |
seconds |
get_wide_priority_differential() |
bool |
|
get_number_of_stages() |
int |
1–4 |
get_two_stage_heat_pump() |
bool |
|
get_stage_on_lag_time() |
int |
minutes |
get_stage_off_lag_time() |
int |
seconds |
get_rotate_cycles() |
int | 'off' |
|
get_rotate_time() |
int | 'off' |
hours |
get_off_staging() |
bool |
|
get_warm_weather_shutdown() |
Temperature | 'off' |
|
get_hot_tank_outdoor_reset() |
Temperature | 'off' |
|
get_hot_tank_differential() |
TemperatureDelta |
|
get_hot_tank_min_temp() |
Temperature |
|
get_hot_tank_max_temp() |
Temperature |
|
get_cold_weather_shutdown() |
Temperature | 'off' |
|
get_cold_tank_outdoor_reset() |
Temperature | 'off' |
|
get_cold_tank_differential() |
TemperatureDelta |
|
get_cold_tank_min_temp() |
Temperature |
|
get_cold_tank_max_temp() |
Temperature |
|
get_dhw_enabled() |
bool |
|
get_dhw_target_temp() |
Temperature |
|
get_dhw_differential() |
TemperatureDelta |
|
get_dhw_state() |
dict |
DHW demand state with activated, enabled, title |
get_demands() |
list[dict] |
All demand channels (hd, cd, dhw) with activated, enabled, name, title |
get_backup_lag_time() |
int | 'off' |
minutes |
get_backup_temp() |
Temperature | 'off' |
|
get_backup_differential() |
TemperatureDelta | 'off' |
|
get_backup_only_outdoor_temp() |
Temperature | 'off' |
|
get_backup_only_tank_temp() |
Temperature | 'off' |
|
get_firmware_version() |
str |
|
get_sync_code() |
str |
|
get_device_pin() |
str |
|
get_device_type() |
str |
e.g. "ECO" |
get_temperatures(temp_name=None) |
dict |
Dict of sensor dicts with actual and target as Temperature objects. Pass temp_name to get one sensor. |
get_runtimes() |
dict |
Stage runtimes as list[timedelta], backup runtime as timedelta |
get_heatpump_stages_state() |
list[dict] |
Stage info with activated, enabled, title, device, index, runTime |
get_backup_state() |
dict |
Backup state with activated, enabled, title, runTime |
get_current_weather() |
dict |
Current conditions: temp, feelsLike, min, max as Temperature; pressure, humidity, wind, windDir, clouds, snow, rain, description, icon, weatherId |
get_forecast() |
list[dict] |
Forecast periods: time as datetime, temp/min/max as Temperature, pop, snow, description, icon, weatherId |
get_system_state() |
dict |
Bundled runtime state: demands, temperatures, stages, backup, pumps, reversingValve, weatherShutdown |
Weather conditions
The description and weatherId fields in weather and forecast data come from OpenWeatherMap. Use weatherId for programmatic checks — it is more reliable than parsing the description string.
| Group | weatherId range |
Example descriptions |
|---|---|---|
| Thunderstorm | 200–232 | "thunderstorm with light rain", "heavy thunderstorm" |
| Drizzle | 300–321 | "light intensity drizzle", "drizzle rain" |
| Rain | 500–531 | "light rain", "moderate rain", "heavy intensity rain" |
| Snow | 600–622 | "light snow", "heavy snow", "sleet" |
| Atmosphere | 701–781 | "mist", "smoke", "haze", "fog", "tornado" |
| Clear | 800 | "clear sky" |
| Clouds | 801–804 | "few clouds", "scattered clouds", "broken clouds", "overcast clouds" |
Setters
All setters accept the value as the first argument. Temperature setters accept int (°F), Temperature, or 'off' where applicable.
| Method | Accepts |
|---|---|
set_hvac_mode_priority(value) |
"heat", "cool", "auto" |
set_permanent_hd(value) |
bool |
set_permanent_cd(value) |
bool |
set_wide_priority_differential(value) |
bool |
set_weather_shutdown_lag_time(value) |
int (0–240 hours) |
set_number_of_stages(value) |
int (1–4) |
set_two_stage_heat_pump(value) |
bool |
set_stage_on_lag_time(value) |
int (1–240 min) |
set_stage_off_lag_time(value) |
int (1–240 sec) |
set_rotate_cycles(value) |
int (1–240) or "off" |
set_rotate_time(value) |
int (1–240 hours) or "off" |
set_off_staging(value) |
bool |
set_heat_cool_switch_delay(value) |
int (30–600 sec) |
set_warm_weather_shutdown(value) |
int (34–180 °F) or "off" |
set_hot_tank_outdoor_reset(value) |
int (-40–127 °F) or "off" |
set_hot_tank_differential(value) |
int (2–100 °F) |
set_hot_tank_min_temp(value) |
int (2–180 °F) |
set_hot_tank_max_temp(value) |
int (2–180 °F) |
set_hot_tank_target_temp(value) |
Alias for set_hot_tank_min_temp |
set_cold_weather_shutdown(value) |
int (33–119 °F) or "off" |
set_cold_tank_outdoor_reset(value) |
int (0–119 °F) or "off" |
set_cold_tank_differential(value) |
int (2–100 °F) |
set_cold_tank_min_temp(value) |
int (2–180 °F) |
set_cold_tank_max_temp(value) |
int (2–180 °F) |
set_cold_tank_target_temp(value) |
Alias for set_cold_tank_min_temp |
set_dhw_enabled(value) |
bool |
set_dhw_target_temp(value) |
Temperature (33–180 °F) |
set_dhw_differential(value) |
TemperatureDelta (2–100 °F) |
set_backup_lag_time(value) |
int (1–240 min) or "off" |
set_backup_temp(value) |
int (2–100 °F) or "off" |
set_backup_differential(value) |
int (2–100 °F) or "off" |
set_backup_only_outdoor_temp(value) |
int (-40–127 °F) or "off" |
set_backup_only_tank_temp(value) |
int (33–200 °F) or "off" |
Exceptions
| Exception | When raised |
|---|---|
LoginError |
Base class for login failures |
InvalidCredentialsError |
Wrong username or password |
LoginTimeoutError |
Login request timed out |
InvalidParameterError |
A setter received an out-of-range or invalid value |
Testing
pip install -e .[tests]
pytest
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pysensorlinx-0.5.2.tar.gz.
File metadata
- Download URL: pysensorlinx-0.5.2.tar.gz
- Upload date:
- Size: 36.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0b7c73ab19675698ae7df1fc143abafc76b723c7674f6e9a6b73b4de5612516
|
|
| MD5 |
8cb99ff7dac2250f3e19f835a57c63c0
|
|
| BLAKE2b-256 |
5ffe5c2f7c4410fbc919e5dd54f8a0f4a67243d43b32f69ede38d47f7b9edb9e
|
Provenance
The following attestation bundles were made for pysensorlinx-0.5.2.tar.gz:
Publisher:
release.yml on sslivins/pysensorlinx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pysensorlinx-0.5.2.tar.gz -
Subject digest:
d0b7c73ab19675698ae7df1fc143abafc76b723c7674f6e9a6b73b4de5612516 - Sigstore transparency entry: 1411024776
- Sigstore integration time:
-
Permalink:
sslivins/pysensorlinx@9dfbc0abd1c0d1eb77a5b84a95ff56fb81cd3c6a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sslivins
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9dfbc0abd1c0d1eb77a5b84a95ff56fb81cd3c6a -
Trigger Event:
push
-
Statement type:
File details
Details for the file pysensorlinx-0.5.2-py3-none-any.whl.
File metadata
- Download URL: pysensorlinx-0.5.2-py3-none-any.whl
- Upload date:
- Size: 32.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1336f84906f3adfc6412b91980c3c87e4b39724d3ed3f0a19934cd5cb76379c4
|
|
| MD5 |
25cfd6d1cc1490deb7dddd8f37e86c23
|
|
| BLAKE2b-256 |
1eac1f160a9e46ed79002c428c550f4cb682ad09d0535d5b5fb8bd42ffa31a01
|
Provenance
The following attestation bundles were made for pysensorlinx-0.5.2-py3-none-any.whl:
Publisher:
release.yml on sslivins/pysensorlinx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pysensorlinx-0.5.2-py3-none-any.whl -
Subject digest:
1336f84906f3adfc6412b91980c3c87e4b39724d3ed3f0a19934cd5cb76379c4 - Sigstore transparency entry: 1411024856
- Sigstore integration time:
-
Permalink:
sslivins/pysensorlinx@9dfbc0abd1c0d1eb77a5b84a95ff56fb81cd3c6a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sslivins
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9dfbc0abd1c0d1eb77a5b84a95ff56fb81cd3c6a -
Trigger Event:
push
-
Statement type: