window-time
A daemon that monitors indoor/outdoor temperatures from InfluxDB and sends notifications when it's time to open or close windows based on the day's forecast.
Installation
pip install window-time
Quick Start
# Initialize configuration file
window-time init
# Edit ~/.config/window-time/config.yaml with your settings
# Then run the daemon
window-time run
Usage
# Run the daemon (checks every 5 minutes)
window-time run
# Run a single check
window-time once
# Show current temperatures and status
window-time status
# Show configuration paths
window-time config
# Show configuration values
window-time config -s
# Enable verbose console logging
window-time -v run
# Log decisions to a file
window-time --log-file /var/log/window-time.log run
# Log decisions with verbose underlying data
window-time --log-file /var/log/window-time.log --log-verbose run
# Use a custom config file
window-time -c /path/to/config.yaml run
Configuration
Configuration is stored in ~/.config/window-time/config.yaml (or equivalent XDG path on your OS).
influxdb:
url: http://localhost:8181
token: your-influxdb-token-here
database: home
measurement: environment
temperature_field: temperature
domain_tag: domain
location_tag: location
mac_tag: mac
indoor_domain: indoors
outdoor_domain: outdoors
notification:
ntfy_topic: your-ntfy-topic-here
ntfy_server: https://ntfy.sh
thresholds:
hot_day_high_temp: 75.0 # Forecast high >= this → hot day (retain cool air)
cold_day_high_temp: 60.0 # Forecast high <= this → cold day (retain warm air)
# Between the two → moderate day (no alerts)
daemon:
interval_minutes: 5
lookback_hours: 1
logging:
log_file: "" # Path to log file (empty = no file logging)
log_verbose: false # Include underlying temperature data in logs
location:
latitude: null # Set to override auto-detection from IP
longitude: null
The InfluxDB token can also be set via the INFLUXDB_TOKEN environment variable.
Logging
The logging section enables decision logging to a file. This is useful for reviewing the daemon's decisions over time.
- log_file: Path to a log file. When set, decisions are logged to this file. Leave empty to disable file logging.
- log_verbose: When
true, logs include detailed underlying data (temperatures, trends, state transitions) in addition to the decision and rationale.
Command-line arguments --log-file and --log-verbose override config file settings.
Example log output (standard):
2024-07-15 14:30:00 - INFO - DECISION: CLOSE | Day mode: hot | Reason: Hot day: outdoor temperature rose above indoor. Close windows to retain cool air inside.
Example log output (verbose):
2024-07-15 14:30:00 - INFO - DECISION: CLOSE | Day mode: hot | Reason: Hot day: outdoor temperature rose above indoor. Close windows to retain cool air inside.
2024-07-15 14:30:00 - DEBUG - Temperature data: indoor=68.5° outdoor=70.2° outdoor_warmer=True
2024-07-15 14:30:00 - DEBUG - State transition: last_outdoor_warmer: False -> True | open_alert_sent: False -> False | close_alert_sent: False -> True | last_known_state: unknown -> closed
2024-07-15 14:30:00 - DEBUG - Indoor trend: rising (+0.25°/hr, confidence=0.89)
2024-07-15 14:30:00 - DEBUG - Outdoor trend: rising (+1.50°/hr, confidence=0.95)
Setting up InfluxDB 3 Core
InfluxDB 3 Core has no concept of organizations, buckets, or per-user accounts — it uses
databases and bearer tokens managed with the influxdb3 CLI.
-
Create the database
influxdb3 create database [my-database-name] -
Create a token
influxdb3 create token --adminCore does not support scoped/read-only tokens (that's an Enterprise/Cloud feature), so the admin token returned here is what you put in
influxdb.token.
Running as a systemd Service
To run window-time as a user service that starts automatically:
-
Copy the service file:
mkdir -p ~/.config/systemd/user cp window-time.service ~/.config/systemd/user/
Or if installed via pip, create the file manually:
cat > ~/.config/systemd/user/window-time.service << 'EOF' [Unit] Description=Window Time - Temperature-based window notification daemon After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=%h/.local/bin/window-time run Restart=on-failure RestartSec=30 [Install] WantedBy=default.target EOF
Note: Adjust
ExecStartpath to match your installation (e.g.,/usr/local/bin/window-timeor%h/.local/bin/window-time). -
Optionally create an environment file for secrets:
cat > ~/.config/window-time/env << 'EOF' INFLUXDB_TOKEN=your-token-here EOF chmod 600 ~/.config/window-time/env
Then add to the
[Service]section:EnvironmentFile=%h/.config/window-time/env -
Enable and start the service:
systemctl --user daemon-reload systemctl --user enable window-time systemctl --user start window-time
-
Check status:
systemctl --user status window-time journalctl --user -u window-time -f
-
Enable lingering (to run service without being logged in):
loginctl enable-linger $USER
How It Works
Day Classification
Each morning the daemon fetches the day's forecast high temperature and classifies the day into one of three modes:
- Hot day (forecast high ≥
hot_day_high_temp, default 75°F): The goal is to retain cool air inside. Windows are closed when outdoor rises above indoor, and opened when outdoor falls below indoor in the evening. - Cold day (forecast high ≤
cold_day_high_temp, default 60°F): The goal is to retain warm air inside. Windows are opened when outdoor rises above indoor (e.g., a sunny afternoon), and closed again when outdoor falls back below indoor. - Moderate day (forecast high between the two thresholds): No window management is needed and no alerts are sent.
Alert Deduplication
At most one open alert and one close alert are sent per day. If temperatures oscillate and cross multiple times in a day, only the first qualifying crossing triggers an alert.
Forecast
The daily forecast is fetched once from Open-Meteo at the start of each day. Location is auto-detected from the server's public IP address via ip-api.com, or can be configured manually with latitude and longitude in the config file.
InfluxDB Data Format
The tool expects temperature data with the following structure:
- Measurement:
environment(configurable) - Field:
temperature(configurable) - Tags:
domain: Eitherindoorsoroutdoorslocation: Description of sensor locationmac: Bluetooth MAC address of the sensor
License
MIT
Metadata
Release files for window-time 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| window_time-0.2.0.tar.gz | 18.8 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| window_time-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.3 kB
Release files / window_time-0.2.0.tar.gz
| Download URL | window_time-0.2.0.tar.gz |
|---|---|
| Size | 18.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a2d698cf7e50bdafcd789890f4f7544f4d64d45285f0fd430ee6757585348d18
|
|
BLAKE2b-256 checksum How to use checksums |
75ed4625f55f457cac80324c32df96c58e82125a102f23d3b08e6b3b5e664bff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / window_time-0.2.0-py3-none-any.whl
| Download URL | window_time-0.2.0-py3-none-any.whl |
|---|---|
| Size | 23.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
223ca3e4c645c39ea22c0513390d83962eb35c1a524923a9b547eeb3262d947f
|
|
BLAKE2b-256 checksum How to use checksums |
1a1a8a052a0bc0a884b41b7948804a09a4e18e7057f78536285c53c2178db30c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logSecurity for window-time 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for window_time-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.