ecobee-local 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 addition-official
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.4
2
+ Name: ecobee-local
3
+ Version: 1.0.0
4
+ Summary: Control an Ecobee thermostat locally over HomeKit. No cloud, no developer key, no Home Assistant.
5
+ Author: addition-official
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 addition-official
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/addition-official/ecobee-local
29
+ Project-URL: Repository, https://github.com/addition-official/ecobee-local
30
+ Project-URL: Issues, https://github.com/addition-official/ecobee-local/issues
31
+ Keywords: ecobee,homekit,thermostat,smart-home,aiohomekit,local
32
+ Classifier: Programming Language :: Python :: 3
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Operating System :: OS Independent
35
+ Classifier: Topic :: Home Automation
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: Intended Audience :: End Users/Desktop
38
+ Requires-Python: >=3.9
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Requires-Dist: aiohomekit>=3.0
42
+ Requires-Dist: zeroconf>=0.130
43
+ Dynamic: license-file
44
+
45
+ # Local Ecobee Control (HomeKit)
46
+
47
+ Control your Ecobee thermostat from Python over your local network, with **no cloud, no OAuth, no ecobee developer key, and no Home Assistant**. It talks to the thermostat directly using Apple's HomeKit Accessory Protocol (HAP) via [`aiohomekit`](https://github.com/Jc2k/aiohomekit).
48
+
49
+ Pair once, then read and control the thermostat from a small control-panel GUI, a command line, or as a Python library you drop into your own project.
50
+
51
+ Works with any HomeKit-capable Ecobee. Developed and tested against an **Ecobee3 lite** and an **Ecobee Smart Premium** (including its remote SmartSensor).
52
+
53
+ ## What it can do
54
+
55
+ - Read current temperature, target, mode, running state, humidity, and fan state
56
+ - Set target temperature, mode (heat / cool / auto / off), heat/cool thresholds, and fan (auto / on)
57
+ - Read remote SmartSensors and the built-in occupancy sensor (temperature, occupancy, battery)
58
+ - Set target humidity on models that have a humidifier/dehumidifier (e.g. Smart Premium)
59
+ - Fahrenheit or Celsius display, with exact half-degree Celsius setting
60
+ - A live GUI that auto-updates, or a scriptable CLI, or an importable library
61
+
62
+ ## Requirements
63
+
64
+ - Python 3.9+
65
+ - `pip install -r requirements.txt` (installs `aiohomekit` and `zeroconf`)
66
+ - Tkinter for the GUI. It ships with Python on Windows and macOS. On some Linux distros it's a separate package: `sudo apt install python3-tk`.
67
+
68
+ ## Setup
69
+
70
+ ### 1. Free the thermostat for pairing
71
+
72
+ HomeKit accessories can only be paired to one "home" at a time. **If your Ecobee is already added to Apple Home, it won't be discoverable for pairing until you reset its HomeKit info.** On the thermostat: **Menu → Settings → HomeKit → Reset HomeKit**. (This removes it from Apple Home. If you don't use Apple Home, there's nothing to do.)
73
+
74
+ ### 2. Pair
75
+
76
+ ```
77
+ python pair_ecobee.py
78
+ ```
79
+
80
+ The wizard will:
81
+ - scan your network and show a numbered list of HomeKit devices (or filter by name),
82
+ - let you pick the thermostat, give it a short label and a friendly name,
83
+ - ask for the 8-digit HomeKit setup code shown on the thermostat screen (type it any way — `12345678`, `1234 5678`, or `123-45-678` all work),
84
+ - save the credentials to a file.
85
+
86
+ Run it again for each additional thermostat. Files are saved to a per-user folder (`%LOCALAPPDATA%\ecobee-local` on Windows, `~/ecobee-local` on macOS/Linux) by default; use `--folder PATH` to change it.
87
+
88
+ > **Keep your pairing files private.** Each one contains long-term keys that grant full control of that thermostat on your network. Don't commit or share them. The included `.gitignore` already excludes them.
89
+
90
+ ### 3. Run
91
+
92
+ ```
93
+ python ecobee_controller.py
94
+ ```
95
+
96
+ With no arguments this opens the **control window** (one card per thermostat). On a headless machine with no display it automatically falls back to a background service instead.
97
+
98
+ ## Command line
99
+
100
+ Everything the GUI does is also scriptable. All `--set-*` actions require `--label`.
101
+
102
+ ```
103
+ python ecobee_controller.py # open the GUI
104
+ python ecobee_controller.py --dump # list every characteristic each thermostat exposes
105
+ python ecobee_controller.py --dump --raw # same, without truncating long values
106
+ python ecobee_controller.py --label main --set-temp 72
107
+ python ecobee_controller.py --label main --set-mode 2 # 0=off 1=heat 2=cool 3=auto
108
+ python ecobee_controller.py --label main --set-heat 68 --set-cool 75 # auto-mode range
109
+ python ecobee_controller.py --label main --set-fan on
110
+ python ecobee_controller.py --headless # run as a background service (no GUI)
111
+ python ecobee_controller.py --debug # print connection/subscription events
112
+ python ecobee_controller.py --folder PATH # use a different credentials folder
113
+ ```
114
+
115
+ `--dump` is the tool for discovering what your specific model exposes: it prints every accessory, service, and characteristic with its UUID, current value, permissions, and range.
116
+
117
+ ## Use it as a library
118
+
119
+ ```python
120
+ from ecobee_controller import EcobeeController
121
+
122
+ ec = EcobeeController.from_folder() # auto-discovers every pairing file
123
+ ec.start()
124
+
125
+ print(ec.get_status("main"))
126
+ # {'current_temp': 78, 'target_temp': 75, 'mode': 2, 'humidity': 57,
127
+ # 'setpoint_kind': 'single', 'display_target': 75, 'sensors': [...], ...}
128
+
129
+ ec.set_temp("main", 72) # Fahrenheit
130
+ ec.set_temp_c("main", 22.5) # Celsius, exact half-degree
131
+ ec.set_mode("main", EcobeeController.MODE_COOL)
132
+ ec.set_heat_threshold("main", 68) # auto mode
133
+ ec.set_cool_threshold("main", 75)
134
+ ec.set_fan("main", auto=True)
135
+
136
+ ec.stop() # cleanly close connections
137
+ ```
138
+
139
+ `get_status()` returns a dict per thermostat. A few fields are computed for convenience:
140
+
141
+ - `setpoint_kind` is `"single"` in heat/cool/off and `"range"` in auto.
142
+ - `display_target` is the value(s) a UI should show: one number in single-setpoint modes, `{"heat": ..., "cool": ...}` in auto.
143
+ - In auto mode `target_temp` is `None`, because a single target is meaningless there — the thermostat runs off the heat/cool thresholds. Read `heat_threshold` / `cool_threshold` (or `display_target`) instead.
144
+ - Temperatures are in Fahrenheit; the raw Celsius the device reports is also included as `*_c` (e.g. `target_temp_c`).
145
+ - Fields a given model doesn't support read as `"--"` rather than a misleading `0`.
146
+
147
+ ## How it works
148
+
149
+ `pair_ecobee.py` performs the one-time HomeKit handshake and saves credentials. `ecobee_controller.py` uses those credentials to keep a persistent local connection per thermostat, subscribes for push updates (the device notifies it on change), and caches readings so the GUI/CLI never block on the network. Characteristics are located by their standard HomeKit type inside the thermostat's Thermostat service, so the same code works across different Ecobee models without hardcoding.
150
+
151
+ ## Notes and limitations
152
+
153
+ - **This is local HomeKit control.** It reads and controls whatever the thermostat exposes over HomeKit.
154
+ - **Air quality is not available.** The Smart Premium has an air-quality sensor, but Ecobee does **not** publish air quality (VOC / CO₂) over HomeKit — only through their cloud. So no local tool, including this one, Apple Home, or Home Assistant, can read it over HomeKit.
155
+ - **The Ecobee app and HomeKit can briefly disagree.** Ecobee drives its own screen and app from its cloud/comfort-profile system. If you change settings in the **ecobee app**, the standard HomeKit state this tool reads may show a different or stale value (for example, showing "Auto" with an odd range) until the setting is next changed **through HomeKit**. Changes made with this tool are always consistent. This is an Ecobee behavior, not a bug in this project.
156
+ - **Scheduling isn't a HomeKit feature.** HomeKit has no concept of a weekly schedule; Ecobee's comfort schedules live in its own system. You can build time-based automation on top of this library, but it can't read/write Ecobee's schedules over HomeKit.
157
+
158
+ ## Files
159
+
160
+ - `pair_ecobee.py` — one-time pairing wizard
161
+ - `ecobee_controller.py` — the library, CLI, and GUI (all in one)
162
+ - `requirements.txt` — dependencies
163
+ - `.gitignore` — keeps pairing credentials out of version control
164
+
165
+ ## Acknowledgements
166
+
167
+ Built on [`aiohomekit`](https://github.com/Jc2k/aiohomekit), the same HomeKit client that powers Home Assistant's HomeKit Controller integration.
@@ -0,0 +1,123 @@
1
+ # Local Ecobee Control (HomeKit)
2
+
3
+ Control your Ecobee thermostat from Python over your local network, with **no cloud, no OAuth, no ecobee developer key, and no Home Assistant**. It talks to the thermostat directly using Apple's HomeKit Accessory Protocol (HAP) via [`aiohomekit`](https://github.com/Jc2k/aiohomekit).
4
+
5
+ Pair once, then read and control the thermostat from a small control-panel GUI, a command line, or as a Python library you drop into your own project.
6
+
7
+ Works with any HomeKit-capable Ecobee. Developed and tested against an **Ecobee3 lite** and an **Ecobee Smart Premium** (including its remote SmartSensor).
8
+
9
+ ## What it can do
10
+
11
+ - Read current temperature, target, mode, running state, humidity, and fan state
12
+ - Set target temperature, mode (heat / cool / auto / off), heat/cool thresholds, and fan (auto / on)
13
+ - Read remote SmartSensors and the built-in occupancy sensor (temperature, occupancy, battery)
14
+ - Set target humidity on models that have a humidifier/dehumidifier (e.g. Smart Premium)
15
+ - Fahrenheit or Celsius display, with exact half-degree Celsius setting
16
+ - A live GUI that auto-updates, or a scriptable CLI, or an importable library
17
+
18
+ ## Requirements
19
+
20
+ - Python 3.9+
21
+ - `pip install -r requirements.txt` (installs `aiohomekit` and `zeroconf`)
22
+ - Tkinter for the GUI. It ships with Python on Windows and macOS. On some Linux distros it's a separate package: `sudo apt install python3-tk`.
23
+
24
+ ## Setup
25
+
26
+ ### 1. Free the thermostat for pairing
27
+
28
+ HomeKit accessories can only be paired to one "home" at a time. **If your Ecobee is already added to Apple Home, it won't be discoverable for pairing until you reset its HomeKit info.** On the thermostat: **Menu → Settings → HomeKit → Reset HomeKit**. (This removes it from Apple Home. If you don't use Apple Home, there's nothing to do.)
29
+
30
+ ### 2. Pair
31
+
32
+ ```
33
+ python pair_ecobee.py
34
+ ```
35
+
36
+ The wizard will:
37
+ - scan your network and show a numbered list of HomeKit devices (or filter by name),
38
+ - let you pick the thermostat, give it a short label and a friendly name,
39
+ - ask for the 8-digit HomeKit setup code shown on the thermostat screen (type it any way — `12345678`, `1234 5678`, or `123-45-678` all work),
40
+ - save the credentials to a file.
41
+
42
+ Run it again for each additional thermostat. Files are saved to a per-user folder (`%LOCALAPPDATA%\ecobee-local` on Windows, `~/ecobee-local` on macOS/Linux) by default; use `--folder PATH` to change it.
43
+
44
+ > **Keep your pairing files private.** Each one contains long-term keys that grant full control of that thermostat on your network. Don't commit or share them. The included `.gitignore` already excludes them.
45
+
46
+ ### 3. Run
47
+
48
+ ```
49
+ python ecobee_controller.py
50
+ ```
51
+
52
+ With no arguments this opens the **control window** (one card per thermostat). On a headless machine with no display it automatically falls back to a background service instead.
53
+
54
+ ## Command line
55
+
56
+ Everything the GUI does is also scriptable. All `--set-*` actions require `--label`.
57
+
58
+ ```
59
+ python ecobee_controller.py # open the GUI
60
+ python ecobee_controller.py --dump # list every characteristic each thermostat exposes
61
+ python ecobee_controller.py --dump --raw # same, without truncating long values
62
+ python ecobee_controller.py --label main --set-temp 72
63
+ python ecobee_controller.py --label main --set-mode 2 # 0=off 1=heat 2=cool 3=auto
64
+ python ecobee_controller.py --label main --set-heat 68 --set-cool 75 # auto-mode range
65
+ python ecobee_controller.py --label main --set-fan on
66
+ python ecobee_controller.py --headless # run as a background service (no GUI)
67
+ python ecobee_controller.py --debug # print connection/subscription events
68
+ python ecobee_controller.py --folder PATH # use a different credentials folder
69
+ ```
70
+
71
+ `--dump` is the tool for discovering what your specific model exposes: it prints every accessory, service, and characteristic with its UUID, current value, permissions, and range.
72
+
73
+ ## Use it as a library
74
+
75
+ ```python
76
+ from ecobee_controller import EcobeeController
77
+
78
+ ec = EcobeeController.from_folder() # auto-discovers every pairing file
79
+ ec.start()
80
+
81
+ print(ec.get_status("main"))
82
+ # {'current_temp': 78, 'target_temp': 75, 'mode': 2, 'humidity': 57,
83
+ # 'setpoint_kind': 'single', 'display_target': 75, 'sensors': [...], ...}
84
+
85
+ ec.set_temp("main", 72) # Fahrenheit
86
+ ec.set_temp_c("main", 22.5) # Celsius, exact half-degree
87
+ ec.set_mode("main", EcobeeController.MODE_COOL)
88
+ ec.set_heat_threshold("main", 68) # auto mode
89
+ ec.set_cool_threshold("main", 75)
90
+ ec.set_fan("main", auto=True)
91
+
92
+ ec.stop() # cleanly close connections
93
+ ```
94
+
95
+ `get_status()` returns a dict per thermostat. A few fields are computed for convenience:
96
+
97
+ - `setpoint_kind` is `"single"` in heat/cool/off and `"range"` in auto.
98
+ - `display_target` is the value(s) a UI should show: one number in single-setpoint modes, `{"heat": ..., "cool": ...}` in auto.
99
+ - In auto mode `target_temp` is `None`, because a single target is meaningless there — the thermostat runs off the heat/cool thresholds. Read `heat_threshold` / `cool_threshold` (or `display_target`) instead.
100
+ - Temperatures are in Fahrenheit; the raw Celsius the device reports is also included as `*_c` (e.g. `target_temp_c`).
101
+ - Fields a given model doesn't support read as `"--"` rather than a misleading `0`.
102
+
103
+ ## How it works
104
+
105
+ `pair_ecobee.py` performs the one-time HomeKit handshake and saves credentials. `ecobee_controller.py` uses those credentials to keep a persistent local connection per thermostat, subscribes for push updates (the device notifies it on change), and caches readings so the GUI/CLI never block on the network. Characteristics are located by their standard HomeKit type inside the thermostat's Thermostat service, so the same code works across different Ecobee models without hardcoding.
106
+
107
+ ## Notes and limitations
108
+
109
+ - **This is local HomeKit control.** It reads and controls whatever the thermostat exposes over HomeKit.
110
+ - **Air quality is not available.** The Smart Premium has an air-quality sensor, but Ecobee does **not** publish air quality (VOC / CO₂) over HomeKit — only through their cloud. So no local tool, including this one, Apple Home, or Home Assistant, can read it over HomeKit.
111
+ - **The Ecobee app and HomeKit can briefly disagree.** Ecobee drives its own screen and app from its cloud/comfort-profile system. If you change settings in the **ecobee app**, the standard HomeKit state this tool reads may show a different or stale value (for example, showing "Auto" with an odd range) until the setting is next changed **through HomeKit**. Changes made with this tool are always consistent. This is an Ecobee behavior, not a bug in this project.
112
+ - **Scheduling isn't a HomeKit feature.** HomeKit has no concept of a weekly schedule; Ecobee's comfort schedules live in its own system. You can build time-based automation on top of this library, but it can't read/write Ecobee's schedules over HomeKit.
113
+
114
+ ## Files
115
+
116
+ - `pair_ecobee.py` — one-time pairing wizard
117
+ - `ecobee_controller.py` — the library, CLI, and GUI (all in one)
118
+ - `requirements.txt` — dependencies
119
+ - `.gitignore` — keeps pairing credentials out of version control
120
+
121
+ ## Acknowledgements
122
+
123
+ Built on [`aiohomekit`](https://github.com/Jc2k/aiohomekit), the same HomeKit client that powers Home Assistant's HomeKit Controller integration.
@@ -0,0 +1,17 @@
1
+ """
2
+ ecobee-local: control an Ecobee thermostat locally over Apple HomeKit,
3
+ with no cloud, no ecobee developer key, and no Home Assistant.
4
+
5
+ Typical use:
6
+
7
+ from ecobee_local import EcobeeController
8
+ ec = EcobeeController.from_folder()
9
+ ec.start()
10
+ ec.set_temp("main", 72)
11
+ ec.stop()
12
+ """
13
+
14
+ from .controller import EcobeeController, default_app_folder
15
+
16
+ __version__ = "1.0.0"
17
+ __all__ = ["EcobeeController", "default_app_folder"]