Metadata-Version: 2.4 Name: pyHomee Version: 1.4.0 Summary: a python library to interact with homee Author: Taraman17 License-Expression: MIT Project-URL: Repository, https://github.com/Taraman17/pyHomee Classifier: Programming Language :: Python :: 3 Classifier: Operating System :: OS Independent Requires-Python: >=3.11 Description-Content-Type: text/markdown License-File: LICENSE Requires-Dist: aiohttp>=3.11 Requires-Dist: websockets>=13 Dynamic: license-file # pyHomee ![PyPI](https://img.shields.io/pypi/v/pyHomee?style=for-the-badge) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pyHomee?color=blue&logo=python&logoColor=yellow&style=for-the-badge) ![GitHub last commit](https://img.shields.io/github/last-commit/Taraman17/pyHomee?style=for-the-badge) > pyHomee is the backbone of the [Home Assistant homee integration](https://github.com/Taraman17/hass-homee). 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. Large parts of this library are directly ported from the awesome [homeeApi](https://github.com/stfnhmplr/homee-api) javascript library. This library was initially developed as "pymee" by [FreshlyBrewedCode](https://github.com/FreshlyBrewedCode/pymee). ## Installation Install from [PyPI](https://pypi.org/project/pyHomee/): ``` pip install pyHomee ``` ## Usage ### Getting started pyHomee should be used with `asyncio`: ```python from pyHomee import Homee import asyncio import logging # Set debug level so we get verbose logs logging.getLogger().setLevel(logging.DEBUG) # Define a simple async entry point function async def main(): # Create an instance of Homee homee = Homee("", "", "") # Connect and start listening on a new task homeeTask = asyncio.create_task(homee.run()) # Wait until the connection is live and all data has been received await homee.wait_until_connected() # Do something here... # Close the connection and wait until we are disconnected homee.disconnect() await homee.wait_until_disconnected() # Start our entry point function asyncio.run(main()) ``` ### Access devices and attributes Devices are represented as "nodes" in the api. All nodes are available in the list `Homee.nodes` and are represented by the `HomeeNode` class. 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. If you need to change the value of an attribute you can use `Homee.set_value()`: ```python # Get some node, for example using get_node_by_id node = homee.get_node_by_id(5) # Turn on the device. You need to pass the id of the node and the attribute as well as the value. # Using get_attribute_by_type you can quickly find the desired attribute. await homee.set_value(node.id, node.get_attribute_by_type(AttributeType.ON_OFF).id, 1) ``` ### Receiving updates The `Homee` class can be inherited to receive events: ```python class MyHomee(Homee): # Called once the websocket connection has been established. async def on_connected(self): pass # Called after the websocket connection has been closed. async def on_disconnected(self): pass # Called after an error has occurred. async def on_error(self, error: str): pass # Called when the websocket receives a message. # The message is automatically parsed from json into a dictionary. async def on_message(self, msg: dict): pass # Called when an 'attribute' message was received and an attribute was updated. # Contains the parsed json attribute data and the corresponding node instance. async def on_attribute_updated(self, attribute_data: dict, node: HomeeNode): pass ``` You can also add a listener to specific nodes to receive attribute updates: ```python # A listener is just a function that takes a node and an attribute def my_node_handler(node: HomeeNode, attribute: HomeeAttribute): logging.info(f"Attribute {attribute.id} of node {node.name} was updated!") node = homee.get_node_by_id(5) # Adding the listener will return a function that can be called to remove the listener again remove_listener = node.add_on_changed_listener(my_node_handler) # If you don't need the listener anymore... remove_listener() ``` To manually request updates from Homee, you can use the following functions: ```python homee.update_node(self, nodeId: int) """Request current data for a node.""" homee.update_attribute(self, nodeId: int, attributeId: int) """Request current data for an attribute""" ``` ### More examples Example implementation that dumps all info into a json file and logs whenever a light is turned on or off: ```python from pyHomee.const import NodeProfile, AttributeType from pyHomee.model import HomeeAttribute class JsonHomee(Homee): async def on_message(self, msg: dict): # Homee sends an "all" message at the beginning of each connection # or after 'GET:all' was send. if list(msg)[0] == "all": f = open("homee.json", "w") f.write(json.dumps(msg)) f.close() async def on_attribute_updated(self, attribute_data, node): # Wrap the attribute data with the HomeeAttribute class for easier access attribute = HomeeAttribute(attribute_data) # We only care for changes if attribute.current_value == attribute.target_value: return # Check node profile (the type of device) and attribute type if ( node.profile == NodeProfile.DIMMABLE_EXTENDED_COLOR_LIGHT and attribute.type == AttributeType.ON_OFF ): self._log( f"[Light] {node.name} turned {'on' if attribute.target_value == 1 else 'off'}" ) ``` ## License MIT