Async Python client for the Rain Bird IQ4 cloud API
Project description
pyiq4
Async Python client for the Rain Bird IQ4 cloud API.
Rain Bird's 2.0 firmware moved all schedule management to the IQ4 cloud. The local controller API no longer returns schedule data on firmware 4.98+. This library talks directly to the IQ4 cloud API, giving full read/write access to irrigation programs, stations, runtimes, and start times.
Disclaimer
This project is not affiliated with, endorsed by, or supported by Rain Bird Corporation. Use at your own risk.
Credits
This library is a Python port of rainbird-iq4-cli by @nickustinov, which is the original open-source implementation of the IQ4 cloud API.
Installation
pip install pyiq4
Or with uv:
uv add pyiq4
Requires Python 3.12+. The only runtime dependency is aiohttp.
Quick start
import asyncio
import aiohttp
from pyiq4 import authenticate, RainbirdIQ4Client
async def main():
async with aiohttp.ClientSession() as session:
token = await authenticate(session, "you@example.com", "password")
client = RainbirdIQ4Client(session, token)
controllers = await client.get_controllers()
for c in controllers:
programs = await client.get_programs(c.id)
for p in programs:
print(f"{c.name} / {p.name} adjust={p.seasonal_adjustment}%")
asyncio.run(main())
API
Authentication
token = await authenticate(session, username, password)
Performs the OIDC implicit flow against Rain Bird's identity server. Returns a JWT token (~2 hour lifetime). Store it and pass it to RainbirdIQ4Client; re-authenticate when you get a RainbirdAuthError.
Client
client = RainbirdIQ4Client(session, token)
client.update_token(new_token) # replace token after re-auth
Read operations
await client.get_sites()
await client.get_controllers()
await client.get_connection_status(controller_ids) # real-time MQTT status
await client.get_programs(controller_id)
await client.get_program_detail(program_id) # full object for writes
await client.get_start_times(controller_id)
await client.get_stations(controller_id)
await client.get_station_runtimes(controller_id)
await client.get_program_step(step_id) # full object for writes
Write operations
# Seasonal adjustment / water days
detail = await client.get_program_detail(program_id)
detail.seasonal_adjustment = 130
detail.week_days = format_weekdays(["Mo", "We", "Fr"])
await client.update_program(detail)
# Station runtime
from dataclasses import replace
step = await client.get_program_step(step_id)
await client.update_program_step(replace(step, run_time_ticks=minutes_to_ticks(15)))
# Start times
await client.add_start_time(program_id, "06:00")
await client.delete_start_times(program_id, [start_time_id])
# Program steps (station assignments)
from pyiq4 import NewProgramStep
await client.add_program_steps([NewProgramStep(program_id=p_id, station_id=s_id)])
await client.delete_program_steps([step_id])
Utilities
from pyiq4 import (
minutes_to_ticks, ticks_to_minutes, # runtime conversion
parse_weekdays, format_weekdays, # "MoWeFr" <-> "0101010"
parse_timespan, format_timespan, # "00:10:00" <-> ticks
)
Exceptions
from pyiq4 import RainbirdAuthError, RainbirdAPIError, RainbirdConnectionError
try:
token = await authenticate(session, username, password)
except RainbirdAuthError:
# Bad credentials, token expired, or AWS WAF block
...
except RainbirdConnectionError:
# Network failure
...
except RainbirdAPIError as e:
# Non-2xx API response
print(e.status_code, e.response_body)
Data model
Account → Sites → Controllers (Satellites)
├── Stations (physical valve zones)
└── Programs (A / B / C irrigation schedules)
├── Start times (when to run)
├── Program steps (station → runtime mapping)
└── Seasonal adjustment (% scaling of all runtimes)
License
MIT
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 pyiq4-0.1.2.tar.gz.
File metadata
- Download URL: pyiq4-0.1.2.tar.gz
- Upload date:
- Size: 11.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 |
2448d4066b172d80b4c4fc889abc56f6960cf07322648e6784a02affeb7f205e
|
|
| MD5 |
0ff0ced791da6e10d96bbf0c37e5ed94
|
|
| BLAKE2b-256 |
fdd8fec90cc7fbf817942eba8d3b30b4c487fb57ae58183d6b8fde53320c0c08
|
Provenance
The following attestation bundles were made for pyiq4-0.1.2.tar.gz:
Publisher:
publish.yml on tiagomota/pyiq4
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyiq4-0.1.2.tar.gz -
Subject digest:
2448d4066b172d80b4c4fc889abc56f6960cf07322648e6784a02affeb7f205e - Sigstore transparency entry: 1331427843
- Sigstore integration time:
-
Permalink:
tiagomota/pyiq4@d365480774795fe5e1f37660c5b66c4abb9261ff -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tiagomota
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d365480774795fe5e1f37660c5b66c4abb9261ff -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyiq4-0.1.2-py3-none-any.whl.
File metadata
- Download URL: pyiq4-0.1.2-py3-none-any.whl
- Upload date:
- Size: 14.1 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 |
9f163cc9d2328d16e19fb48d0d0a7953ff4c89e14f5878c20b0dfa4507b1f41d
|
|
| MD5 |
4ccd97975f4f3bf307491941bbfebc1d
|
|
| BLAKE2b-256 |
5d235adbcc1a01d5b15855990d61b47cb74bb375b9ecdc5bc50064ad8e8e0b00
|
Provenance
The following attestation bundles were made for pyiq4-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on tiagomota/pyiq4
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyiq4-0.1.2-py3-none-any.whl -
Subject digest:
9f163cc9d2328d16e19fb48d0d0a7953ff4c89e14f5878c20b0dfa4507b1f41d - Sigstore transparency entry: 1331428006
- Sigstore integration time:
-
Permalink:
tiagomota/pyiq4@d365480774795fe5e1f37660c5b66c4abb9261ff -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tiagomota
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d365480774795fe5e1f37660c5b66c4abb9261ff -
Trigger Event:
push
-
Statement type: