No description
- Rust 58.1%
- Swift 13.6%
- Kotlin 11.5%
- Python 10.6%
- Shell 4.1%
- Other 2.1%
| homeassistant/custom_components/tylo | ||
| i18n | ||
| tylo-android | ||
| tylo-cli | ||
| tylo-core | ||
| tylo-ffi | ||
| tylo-ios | ||
| tylo-python | ||
| .envrc | ||
| .gitignore | ||
| build-android.sh | ||
| build-ios.sh | ||
| Cargo.lock | ||
| Cargo.toml | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
Tylo
Unofficial tools for controlling Tylö saunas. Reverse-engineered from the
Tylo Control Android app — uses the same protobuf-over-UDP protocol locally
and the same REST + WebSocket cloud API at remote.tylohelo.com.
Workspace
| Crate | Description |
|---|---|
tylo-core |
Rust library — discovery, connection, commands, cloud API, proto codegen |
tylo-cli |
CLI binary (tylo) — status, control, watch, cloud pairing |
tylo-python |
PyO3 bindings — build with maturin develop |
homeassistant/custom_components/tylo/ is a Home Assistant integration
(climate + light + sensors) that uses the Python bindings.
Build
cargo build # core + cli + python bindings
cargo build -p tylo-cli # cli only
cd tylo-python && maturin develop # install python module
CLI usage
tylo discover # find saunas on the network
tylo status --ip 192.168.1.X # one-shot status
tylo watch --ip 192.168.1.X # live-updating status
tylo on --ip 192.168.1.X # turn on
tylo off --ip 192.168.1.X # turn off
tylo set --ip 192.168.1.X --temp 80 --humidity 20 --time 60
tylo cloud-pair # opens a local web page to scan the sauna QR code
tylo cloud-status # status via cloud API
tylo cloud-watch # live status via cloud WebSocket
Home Assistant
services.home-assistant = {
enable = true;
services.home-assistant.customComponents = [
pkgs.home-assistant-custom-components.tylo
];
};
Protocol notes
- Local: protobuf (
tylohelopackage) over raw UDP, default port 51113 - Temperature encoding:
raw = celsius * 9(e.g. 75 °C = 675) - Cloud: same protobuf messages, base64url-encoded over WebSocket
- State inference: the sauna doesn't always send explicit state — ON/OFF/STANDBY
is inferred from
RunTimeLeftandStandbyEnablevalues when needed