pyHomee 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.
- pyhomee-1.0.0/LICENSE +21 -0
- pyhomee-1.0.0/PKG-INFO +179 -0
- pyhomee-1.0.0/README.md +166 -0
- pyhomee-1.0.0/pyHomee.egg-info/PKG-INFO +179 -0
- pyhomee-1.0.0/pyHomee.egg-info/SOURCES.txt +11 -0
- pyhomee-1.0.0/pyHomee.egg-info/dependency_links.txt +1 -0
- pyhomee-1.0.0/pyHomee.egg-info/top_level.txt +1 -0
- pyhomee-1.0.0/pymee/__init__.py +580 -0
- pyhomee-1.0.0/pymee/const.py +1188 -0
- pyhomee-1.0.0/pymee/model.py +992 -0
- pyhomee-1.0.0/pyproject.toml +4 -0
- pyhomee-1.0.0/setup.cfg +4 -0
- pyhomee-1.0.0/setup.py +23 -0
pyhomee-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Karl Moeller
|
|
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.
|
pyhomee-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pyHomee
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: a python library to interact with homee
|
|
5
|
+
Home-page: https://github.com/Taraman17/pyHomee
|
|
6
|
+
Author: Taraman17
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.6
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
|
|
14
|
+
# pyhomee
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+

|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
> pyHomee is the backbone of the [Home Assistant homee integration](https://github.com/Taraman17/hass-homee).
|
|
21
|
+
|
|
22
|
+
pyHomee is an unofficial python library for interacting with the [homee](https://hom.ee) smart home/home automation platform. It uses the [websockets](https://github.com/aaugustin/websockets) library to connect to a local homee cube and maintains a list of nodes (devices), attributes, groups, users and more that are updated whenever new data arrives from homee.
|
|
23
|
+
|
|
24
|
+
Large parts of this library are directly ported from the awesome [homeeApi](https://github.com/stfnhmplr/homee-api) javascript library.
|
|
25
|
+
|
|
26
|
+
This library was initially developed as "pymee" by [FreshlyBrewedCode](https://github.com/FreshlyBrewedCode/pymee).
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
Install from [PyPI](https://pypi.org/project/pyhomee/):
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
pip install pyhomee
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
### Getting started
|
|
39
|
+
|
|
40
|
+
pyHomee should be used with `asyncio`:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from pyhomee import Homee
|
|
44
|
+
import asyncio
|
|
45
|
+
import logging
|
|
46
|
+
|
|
47
|
+
# Set debug level so we get verbose logs
|
|
48
|
+
logging.getLogger().setLevel(logging.DEBUG)
|
|
49
|
+
|
|
50
|
+
# Define a simple async entry point function
|
|
51
|
+
async def main():
|
|
52
|
+
# Create an instance of Homee
|
|
53
|
+
homee = Homee("<HOMEE IP>", "<USERNAME>", "<PASSWORD>")
|
|
54
|
+
|
|
55
|
+
# Connect and start listening on a new task
|
|
56
|
+
homeeTask = asyncio.create_task(homee.run())
|
|
57
|
+
|
|
58
|
+
# Wait until the connection is live and all data has been received
|
|
59
|
+
await homee.wait_until_connected()
|
|
60
|
+
|
|
61
|
+
# Do something here...
|
|
62
|
+
|
|
63
|
+
# Close the connection and wait until we are disconnected
|
|
64
|
+
homee.disconnect()
|
|
65
|
+
await homee.wait_until_disconnected()
|
|
66
|
+
|
|
67
|
+
# Start our entry point function
|
|
68
|
+
asyncio.run(main())
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Access devices and attributes
|
|
72
|
+
|
|
73
|
+
Devices are represented as "nodes" in the api. All nodes are available in the list `Homee.nodes` and are represented by the `HomeeNode` class.
|
|
74
|
+
Each node has a list of attributes accessible from `HomeeNode.attributes`. The attributes on a node represent the different attributes on a device, i.e. if a light is turned on or the target temperature of a thermostat. Attributes can be identified by the `HomeeAttribute.type` property. You can compare the type with the values from `pyhomee.const.AttributeType` to figure out what each attribute represents. The value can be accessed with the `HomeeAttribute.current_value` property.
|
|
75
|
+
|
|
76
|
+
If you need to change the value of an attribute you can use `Homee.set_value()`:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
# Get some node, for example using get_node_by_id
|
|
80
|
+
node = homee.get_node_by_id(5)
|
|
81
|
+
|
|
82
|
+
# Turn on the device. You need to pass the id of the node and the attribute as well as the value.
|
|
83
|
+
# Using get_attribute_by_type you can quickly find the desired attribute.
|
|
84
|
+
await homee.set_value(node.id, node.get_attribute_by_type(AttributeType.ON_OFF).id, 1)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Receiving updates
|
|
88
|
+
|
|
89
|
+
The `Homee` class can be inherited to receive events:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
class MyHomee(Homee):
|
|
93
|
+
# Called once the websocket connection has been established.
|
|
94
|
+
async def on_connected(self):
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
# Called after the websocket connection has been closed.
|
|
98
|
+
async def on_disconnected(self):
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
# Called after an error has occurred.
|
|
102
|
+
async def on_error(self, error: str):
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
# Called when the websocket receives a message.
|
|
106
|
+
# The message is automatically parsed from json into a dictionary.
|
|
107
|
+
async def on_message(self, msg: dict):
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
# Called when an 'attribute' message was received and an attribute was updated.
|
|
111
|
+
# Contains the parsed json attribute data and the corresponding node instance.
|
|
112
|
+
async def on_attribute_updated(self, attribute_data: dict, node: HomeeNode):
|
|
113
|
+
pass
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
You can also add a listener to specific nodes to receive attribute updates:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
# A listener is just a function that takes a node and an attribute
|
|
120
|
+
def my_node_handler(node: HomeeNode, attribute: HomeeAttribute):
|
|
121
|
+
logging.info(f"Attribute {attribute.id} of node {node.name} was updated!")
|
|
122
|
+
|
|
123
|
+
node = homee.get_node_by_id(5)
|
|
124
|
+
|
|
125
|
+
# Adding the listener will return a function that can be called to remove the listener again
|
|
126
|
+
remove_listener = node.add_on_changed_listener(my_node_handler)
|
|
127
|
+
|
|
128
|
+
# If you don't need the listener anymore...
|
|
129
|
+
remove_listener()
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
To manually request updates from Homee, you can use the following functions:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
homee.update_node(self, nodeId: int)
|
|
136
|
+
"""Request current data for a node."""
|
|
137
|
+
|
|
138
|
+
homee.update_attribute(self, nodeId: int, attributeId: int)
|
|
139
|
+
"""Request current data for an attribute"""
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### More examples
|
|
143
|
+
|
|
144
|
+
Example implementation that dumps all info into a json file and logs whenever a light is turned on or off:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from pyhomee.const import NodeProfile, AttributeType
|
|
148
|
+
from pyhomee.model import HomeeAttribute
|
|
149
|
+
|
|
150
|
+
class JsonHomee(Homee):
|
|
151
|
+
async def on_message(self, msg: dict):
|
|
152
|
+
# Homee sends an "all" message at the beginning of each connection
|
|
153
|
+
# or after 'GET:all' was send.
|
|
154
|
+
if list(msg)[0] == "all":
|
|
155
|
+
f = open("homee.json", "w")
|
|
156
|
+
f.write(json.dumps(msg))
|
|
157
|
+
f.close()
|
|
158
|
+
|
|
159
|
+
async def on_attribute_updated(self, attribute_data, node):
|
|
160
|
+
# Wrap the attribute data with the HomeeAttribute class for easier access
|
|
161
|
+
attribute = HomeeAttribute(attribute_data)
|
|
162
|
+
|
|
163
|
+
# We only care for changes
|
|
164
|
+
if attribute.current_value == attribute.target_value:
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
# Check node profile (the type of device) and attribute type
|
|
168
|
+
if (
|
|
169
|
+
node.profile == NodeProfile.DIMMABLE_EXTENDED_COLOR_LIGHT
|
|
170
|
+
and attribute.type == AttributeType.ON_OFF
|
|
171
|
+
):
|
|
172
|
+
self._log(
|
|
173
|
+
f"[Light] {node.name} turned {'on' if attribute.target_value == 1 else 'off'}"
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
MIT
|
pyhomee-1.0.0/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# pyhomee
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
> pyHomee is the backbone of the [Home Assistant homee integration](https://github.com/Taraman17/hass-homee).
|
|
8
|
+
|
|
9
|
+
pyHomee is an unofficial python library for interacting with the [homee](https://hom.ee) smart home/home automation platform. It uses the [websockets](https://github.com/aaugustin/websockets) library to connect to a local homee cube and maintains a list of nodes (devices), attributes, groups, users and more that are updated whenever new data arrives from homee.
|
|
10
|
+
|
|
11
|
+
Large parts of this library are directly ported from the awesome [homeeApi](https://github.com/stfnhmplr/homee-api) javascript library.
|
|
12
|
+
|
|
13
|
+
This library was initially developed as "pymee" by [FreshlyBrewedCode](https://github.com/FreshlyBrewedCode/pymee).
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Install from [PyPI](https://pypi.org/project/pyhomee/):
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
pip install pyhomee
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Getting started
|
|
26
|
+
|
|
27
|
+
pyHomee should be used with `asyncio`:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from pyhomee import Homee
|
|
31
|
+
import asyncio
|
|
32
|
+
import logging
|
|
33
|
+
|
|
34
|
+
# Set debug level so we get verbose logs
|
|
35
|
+
logging.getLogger().setLevel(logging.DEBUG)
|
|
36
|
+
|
|
37
|
+
# Define a simple async entry point function
|
|
38
|
+
async def main():
|
|
39
|
+
# Create an instance of Homee
|
|
40
|
+
homee = Homee("<HOMEE IP>", "<USERNAME>", "<PASSWORD>")
|
|
41
|
+
|
|
42
|
+
# Connect and start listening on a new task
|
|
43
|
+
homeeTask = asyncio.create_task(homee.run())
|
|
44
|
+
|
|
45
|
+
# Wait until the connection is live and all data has been received
|
|
46
|
+
await homee.wait_until_connected()
|
|
47
|
+
|
|
48
|
+
# Do something here...
|
|
49
|
+
|
|
50
|
+
# Close the connection and wait until we are disconnected
|
|
51
|
+
homee.disconnect()
|
|
52
|
+
await homee.wait_until_disconnected()
|
|
53
|
+
|
|
54
|
+
# Start our entry point function
|
|
55
|
+
asyncio.run(main())
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Access devices and attributes
|
|
59
|
+
|
|
60
|
+
Devices are represented as "nodes" in the api. All nodes are available in the list `Homee.nodes` and are represented by the `HomeeNode` class.
|
|
61
|
+
Each node has a list of attributes accessible from `HomeeNode.attributes`. The attributes on a node represent the different attributes on a device, i.e. if a light is turned on or the target temperature of a thermostat. Attributes can be identified by the `HomeeAttribute.type` property. You can compare the type with the values from `pyhomee.const.AttributeType` to figure out what each attribute represents. The value can be accessed with the `HomeeAttribute.current_value` property.
|
|
62
|
+
|
|
63
|
+
If you need to change the value of an attribute you can use `Homee.set_value()`:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
# Get some node, for example using get_node_by_id
|
|
67
|
+
node = homee.get_node_by_id(5)
|
|
68
|
+
|
|
69
|
+
# Turn on the device. You need to pass the id of the node and the attribute as well as the value.
|
|
70
|
+
# Using get_attribute_by_type you can quickly find the desired attribute.
|
|
71
|
+
await homee.set_value(node.id, node.get_attribute_by_type(AttributeType.ON_OFF).id, 1)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Receiving updates
|
|
75
|
+
|
|
76
|
+
The `Homee` class can be inherited to receive events:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
class MyHomee(Homee):
|
|
80
|
+
# Called once the websocket connection has been established.
|
|
81
|
+
async def on_connected(self):
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
# Called after the websocket connection has been closed.
|
|
85
|
+
async def on_disconnected(self):
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
# Called after an error has occurred.
|
|
89
|
+
async def on_error(self, error: str):
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
# Called when the websocket receives a message.
|
|
93
|
+
# The message is automatically parsed from json into a dictionary.
|
|
94
|
+
async def on_message(self, msg: dict):
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
# Called when an 'attribute' message was received and an attribute was updated.
|
|
98
|
+
# Contains the parsed json attribute data and the corresponding node instance.
|
|
99
|
+
async def on_attribute_updated(self, attribute_data: dict, node: HomeeNode):
|
|
100
|
+
pass
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
You can also add a listener to specific nodes to receive attribute updates:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
# A listener is just a function that takes a node and an attribute
|
|
107
|
+
def my_node_handler(node: HomeeNode, attribute: HomeeAttribute):
|
|
108
|
+
logging.info(f"Attribute {attribute.id} of node {node.name} was updated!")
|
|
109
|
+
|
|
110
|
+
node = homee.get_node_by_id(5)
|
|
111
|
+
|
|
112
|
+
# Adding the listener will return a function that can be called to remove the listener again
|
|
113
|
+
remove_listener = node.add_on_changed_listener(my_node_handler)
|
|
114
|
+
|
|
115
|
+
# If you don't need the listener anymore...
|
|
116
|
+
remove_listener()
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
To manually request updates from Homee, you can use the following functions:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
homee.update_node(self, nodeId: int)
|
|
123
|
+
"""Request current data for a node."""
|
|
124
|
+
|
|
125
|
+
homee.update_attribute(self, nodeId: int, attributeId: int)
|
|
126
|
+
"""Request current data for an attribute"""
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### More examples
|
|
130
|
+
|
|
131
|
+
Example implementation that dumps all info into a json file and logs whenever a light is turned on or off:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from pyhomee.const import NodeProfile, AttributeType
|
|
135
|
+
from pyhomee.model import HomeeAttribute
|
|
136
|
+
|
|
137
|
+
class JsonHomee(Homee):
|
|
138
|
+
async def on_message(self, msg: dict):
|
|
139
|
+
# Homee sends an "all" message at the beginning of each connection
|
|
140
|
+
# or after 'GET:all' was send.
|
|
141
|
+
if list(msg)[0] == "all":
|
|
142
|
+
f = open("homee.json", "w")
|
|
143
|
+
f.write(json.dumps(msg))
|
|
144
|
+
f.close()
|
|
145
|
+
|
|
146
|
+
async def on_attribute_updated(self, attribute_data, node):
|
|
147
|
+
# Wrap the attribute data with the HomeeAttribute class for easier access
|
|
148
|
+
attribute = HomeeAttribute(attribute_data)
|
|
149
|
+
|
|
150
|
+
# We only care for changes
|
|
151
|
+
if attribute.current_value == attribute.target_value:
|
|
152
|
+
return
|
|
153
|
+
|
|
154
|
+
# Check node profile (the type of device) and attribute type
|
|
155
|
+
if (
|
|
156
|
+
node.profile == NodeProfile.DIMMABLE_EXTENDED_COLOR_LIGHT
|
|
157
|
+
and attribute.type == AttributeType.ON_OFF
|
|
158
|
+
):
|
|
159
|
+
self._log(
|
|
160
|
+
f"[Light] {node.name} turned {'on' if attribute.target_value == 1 else 'off'}"
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
MIT
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pyHomee
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: a python library to interact with homee
|
|
5
|
+
Home-page: https://github.com/Taraman17/pyHomee
|
|
6
|
+
Author: Taraman17
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.6
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
|
|
14
|
+
# pyhomee
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+

|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
> pyHomee is the backbone of the [Home Assistant homee integration](https://github.com/Taraman17/hass-homee).
|
|
21
|
+
|
|
22
|
+
pyHomee is an unofficial python library for interacting with the [homee](https://hom.ee) smart home/home automation platform. It uses the [websockets](https://github.com/aaugustin/websockets) library to connect to a local homee cube and maintains a list of nodes (devices), attributes, groups, users and more that are updated whenever new data arrives from homee.
|
|
23
|
+
|
|
24
|
+
Large parts of this library are directly ported from the awesome [homeeApi](https://github.com/stfnhmplr/homee-api) javascript library.
|
|
25
|
+
|
|
26
|
+
This library was initially developed as "pymee" by [FreshlyBrewedCode](https://github.com/FreshlyBrewedCode/pymee).
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
Install from [PyPI](https://pypi.org/project/pyhomee/):
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
pip install pyhomee
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
### Getting started
|
|
39
|
+
|
|
40
|
+
pyHomee should be used with `asyncio`:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from pyhomee import Homee
|
|
44
|
+
import asyncio
|
|
45
|
+
import logging
|
|
46
|
+
|
|
47
|
+
# Set debug level so we get verbose logs
|
|
48
|
+
logging.getLogger().setLevel(logging.DEBUG)
|
|
49
|
+
|
|
50
|
+
# Define a simple async entry point function
|
|
51
|
+
async def main():
|
|
52
|
+
# Create an instance of Homee
|
|
53
|
+
homee = Homee("<HOMEE IP>", "<USERNAME>", "<PASSWORD>")
|
|
54
|
+
|
|
55
|
+
# Connect and start listening on a new task
|
|
56
|
+
homeeTask = asyncio.create_task(homee.run())
|
|
57
|
+
|
|
58
|
+
# Wait until the connection is live and all data has been received
|
|
59
|
+
await homee.wait_until_connected()
|
|
60
|
+
|
|
61
|
+
# Do something here...
|
|
62
|
+
|
|
63
|
+
# Close the connection and wait until we are disconnected
|
|
64
|
+
homee.disconnect()
|
|
65
|
+
await homee.wait_until_disconnected()
|
|
66
|
+
|
|
67
|
+
# Start our entry point function
|
|
68
|
+
asyncio.run(main())
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Access devices and attributes
|
|
72
|
+
|
|
73
|
+
Devices are represented as "nodes" in the api. All nodes are available in the list `Homee.nodes` and are represented by the `HomeeNode` class.
|
|
74
|
+
Each node has a list of attributes accessible from `HomeeNode.attributes`. The attributes on a node represent the different attributes on a device, i.e. if a light is turned on or the target temperature of a thermostat. Attributes can be identified by the `HomeeAttribute.type` property. You can compare the type with the values from `pyhomee.const.AttributeType` to figure out what each attribute represents. The value can be accessed with the `HomeeAttribute.current_value` property.
|
|
75
|
+
|
|
76
|
+
If you need to change the value of an attribute you can use `Homee.set_value()`:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
# Get some node, for example using get_node_by_id
|
|
80
|
+
node = homee.get_node_by_id(5)
|
|
81
|
+
|
|
82
|
+
# Turn on the device. You need to pass the id of the node and the attribute as well as the value.
|
|
83
|
+
# Using get_attribute_by_type you can quickly find the desired attribute.
|
|
84
|
+
await homee.set_value(node.id, node.get_attribute_by_type(AttributeType.ON_OFF).id, 1)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Receiving updates
|
|
88
|
+
|
|
89
|
+
The `Homee` class can be inherited to receive events:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
class MyHomee(Homee):
|
|
93
|
+
# Called once the websocket connection has been established.
|
|
94
|
+
async def on_connected(self):
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
# Called after the websocket connection has been closed.
|
|
98
|
+
async def on_disconnected(self):
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
# Called after an error has occurred.
|
|
102
|
+
async def on_error(self, error: str):
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
# Called when the websocket receives a message.
|
|
106
|
+
# The message is automatically parsed from json into a dictionary.
|
|
107
|
+
async def on_message(self, msg: dict):
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
# Called when an 'attribute' message was received and an attribute was updated.
|
|
111
|
+
# Contains the parsed json attribute data and the corresponding node instance.
|
|
112
|
+
async def on_attribute_updated(self, attribute_data: dict, node: HomeeNode):
|
|
113
|
+
pass
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
You can also add a listener to specific nodes to receive attribute updates:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
# A listener is just a function that takes a node and an attribute
|
|
120
|
+
def my_node_handler(node: HomeeNode, attribute: HomeeAttribute):
|
|
121
|
+
logging.info(f"Attribute {attribute.id} of node {node.name} was updated!")
|
|
122
|
+
|
|
123
|
+
node = homee.get_node_by_id(5)
|
|
124
|
+
|
|
125
|
+
# Adding the listener will return a function that can be called to remove the listener again
|
|
126
|
+
remove_listener = node.add_on_changed_listener(my_node_handler)
|
|
127
|
+
|
|
128
|
+
# If you don't need the listener anymore...
|
|
129
|
+
remove_listener()
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
To manually request updates from Homee, you can use the following functions:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
homee.update_node(self, nodeId: int)
|
|
136
|
+
"""Request current data for a node."""
|
|
137
|
+
|
|
138
|
+
homee.update_attribute(self, nodeId: int, attributeId: int)
|
|
139
|
+
"""Request current data for an attribute"""
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### More examples
|
|
143
|
+
|
|
144
|
+
Example implementation that dumps all info into a json file and logs whenever a light is turned on or off:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from pyhomee.const import NodeProfile, AttributeType
|
|
148
|
+
from pyhomee.model import HomeeAttribute
|
|
149
|
+
|
|
150
|
+
class JsonHomee(Homee):
|
|
151
|
+
async def on_message(self, msg: dict):
|
|
152
|
+
# Homee sends an "all" message at the beginning of each connection
|
|
153
|
+
# or after 'GET:all' was send.
|
|
154
|
+
if list(msg)[0] == "all":
|
|
155
|
+
f = open("homee.json", "w")
|
|
156
|
+
f.write(json.dumps(msg))
|
|
157
|
+
f.close()
|
|
158
|
+
|
|
159
|
+
async def on_attribute_updated(self, attribute_data, node):
|
|
160
|
+
# Wrap the attribute data with the HomeeAttribute class for easier access
|
|
161
|
+
attribute = HomeeAttribute(attribute_data)
|
|
162
|
+
|
|
163
|
+
# We only care for changes
|
|
164
|
+
if attribute.current_value == attribute.target_value:
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
# Check node profile (the type of device) and attribute type
|
|
168
|
+
if (
|
|
169
|
+
node.profile == NodeProfile.DIMMABLE_EXTENDED_COLOR_LIGHT
|
|
170
|
+
and attribute.type == AttributeType.ON_OFF
|
|
171
|
+
):
|
|
172
|
+
self._log(
|
|
173
|
+
f"[Light] {node.name} turned {'on' if attribute.target_value == 1 else 'off'}"
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pymee
|