Skip to content

Commit

Permalink
Improved documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelschreiner committed Apr 8, 2024
1 parent ac69852 commit 0c280d1
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 37 deletions.
100 changes: 65 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<img alt="logo" src="docs/main_banner.webp">
</p>

![Pylint](https://github.com/marcelschreiner/hue-to-loxone/actions/workflows/pylint.yml/badge.svg)
[![HitCount](https://hits.dwyl.com/marcelschreiner/hue-to-loxone.svg?style=flat)](http://hits.dwyl.com/marcelschreiner/hue-to-loxone)
![Pylint](https://github.com/marcelschreiner/hue-to-loxone/actions/workflows/pylint.yml/badge.svg)
[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=marcelschreiner_hue-to-loxone&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=marcelschreiner_hue-to-loxone)
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=marcelschreiner_hue-to-loxone&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=marcelschreiner_hue-to-loxone)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=marcelschreiner_hue-to-loxone&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=marcelschreiner_hue-to-loxone)
Expand All @@ -14,64 +14,94 @@
[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=marcelschreiner_hue-to-loxone&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=marcelschreiner_hue-to-loxone)

# Philips Hue to Loxone Bridge
This python script allows you to integrate your Philips Hue smart lighting system with your Loxone system. By running this script, events in the Hue system are forwarded to the Loxone Miniserver in the form of UDP packets. The signal-flow is like this:
```mermaid
graph LR
A[Hue Accessory] --> B[Hue Bridge]
B --> C[✨Philips Hue to Loxone Bridge✨]
C --> D[Loxone Miniserver]
```

This Python script allows you to integrate your Philips Hue smart lighting system with your Loxone Miniserver. By running this script, you can listen for events from your Hue bridge and send corresponding updates to your Loxone Miniserver over UDP.

## Prerequisites

Before you can use this script, you'll need the following:
> [!NOTE]
> This Python script only sends events from the Hue bridge to the Loxone Miniserver. If you want to control your Hue lights from the Miniserver, have a look at [this PicoC script](https://github.com/marcelschreiner/loxone-hue-picoc) that can run on the Miniserver.
- Python 3
- The `aiohue` library
- The IP address and UDP port of your Loxone Miniserver
- The IP address of your Philips Hue bridge
- An API key generated for your Hue bridge (If you dont have a key, you can simple execute the script provided in this repo)
```shell
python3 get_api_key.py
```
<br/>

## Configuration
## Supported Event Types
The bridge is designed to parse the following events. (If you are missing an event type, hit me up and we'll see if i can add it 😎)

Open the script and modify the following variables to match your setup:
| Event Type | Description |
| --- | --- |
| `BUTTON` | This event is triggered when a button on a Hue Dimmer Switch, Hue Button or an other similar device is pressed. The button_state is `1` as long the as the button is pressed and `0` when released. <br/><br/>Note that for BUTTON events, the `{item_state}` has a format of `{button_number}/{button_state}`. This is because a single hue accessory can have multiple buttons. <br/><br/> Example: `hue_event/sensors/29/1/1`|
| `MOTION` | This event is triggered when motion is detected by a Hue motion sensor. The state is `1` when motion is detected and `0` when no motion is detected. <br/><br/> Example: `hue_event/sensors/34/1`|
| `LIGHT_LEVEL` | This event is triggered when the light level changes on a Hue light sensor. The state represents the current light level. To get the actual brightness in Lux, use this formula: 2.718281828459^(value*0.00023034)-1 <br/><br/> Example: `hue_event/sensors/35/10597`|
| `TEMPERATURE` | This event is triggered when the temperature changes on a Hue motion sensor. The state represents the current temperature as a float value. <br/><br/> Example: `hue_event/sensors/36/25.36` = 25.36°C|
| `LIGHT` | This event is triggered when the state of a light changes. The state is `1` when the light is on and `0` when the light is off. <br/><br/> Example: `hue_event/lights/4/1`|
| `GROUPED_LIGHT` | This event is triggered when the state of a light group changes. The state is `1` when the group is on and `0` when the group is off. <br/><br/> Example: `hue_event/groups/3/0`|
| `DEVICE_POWER` | This event is triggered when the battery level of a Hue device changes. The state represents the current battery level. |

- `HUE_IP`: Set this to the IP address of your Philips Hue bridge.
- `HUE_API_KEY`: Set this to your Hue bridge's API key.
- `LOXONE_IP`: Set this to the IP address of your Loxone Miniserver.
- `LOXONE_UDP_PORT`: Set this to the UDP port your Loxone Miniserver is listening on.
Each event is sent to the Loxone Miniserver as a UDP packet in the format `hue_event/{item_type}/{item_id}/{item_state}`. Every Hue item has a unique id. If an item can have multiple different event types, then a unique id for every event type is generated.

## Usage
To make it easier for you to assign the id to a specific item, the python script prints all names and id's during startup.
<br/><br/>

1. Clone this repository or download the script.
## Getting Started
This guide assumes that you have git and python 3 installed on you system. If true, continue with these steps:

2. Install the required dependencies if you haven't already:
(`pip3` is traditionally used on Rapberry Pis to install libraries for Python 3 other systems may use `pip`)
1. Clone this repository.
```shell
git clone https://github.com/marcelschreiner/hue-to-loxone.git
```

2. Install the required dependencies (python libraries) with pip. `pip3` is traditionally used on Raspberry Pis to install libraries for Python 3 other systems may use `pip`.
```shell
pip3 install requests
pip3 install aiohue
```

3. Modify the configuration variables in the script as described in the Configuration section.
3. Generate a Philips Hue API key, to access you Hue bridge. To do this configure the IP of you Hue bridge in `get_api_key.py`. Then execute the script, it will guide you through the process.
```shell
python3 get_api_key.py
```

4. Run the script using the following command:
3. Modify the configuration variables in the `hue2lox.py` script as described in the [Configuration](#configuration) section.

4. Run the Philips Hue to Loxone bridge using the following command:
```shell
python3 hue2lox.py
```

The script will connect to your Philips Hue bridge, subscribe to events, and start listening for changes.
6. OPTIONAL: *(Example for Raspberry Pi)* If you want the python script to automatically start if your system starts, open `rc.local`
```shell
sudo nano /etc/rc.local
```
Then add the path to the `hue2lox.py` script:
```
...
python3 /home/pi/hue2lox.py &
exit 0
```

6. The script will send updates to your Loxone Miniserver whenever there's an event on your Philips Hue system.
## Configuration
Open the script and modify the following variables to match your setup:

## Event Handling
- `HUE_IP`: Set this to the IP address of your Philips Hue bridge.
- `HUE_API_KEY`: Set this to your Hue bridge's API key.
- `LOXONE_IP`: Set this to the IP address of your Loxone Miniserver.
- `LOXONE_UDP_PORT`: Set this to the UDP port your Loxone Miniserver is configured to listening on.
<br/><br/>

The script currently handles events for Philips Hue buttons, motion sensors, and light level sensors. You can customize the event handling logic in the `parse_event` function based on your specific requirements.
Feel free to modify and extend the script to support additional Philips Hue devices.
## Configuring a Virtual UDP Input in Loxone Config
To integrate the Philips Hue events with your Loxone Miniserver, you need to configure a virtual UDP input in the Loxone Config. Follow the steps below:

## License
1. Open the Loxone Config and connect to your Miniserver.

This script is provided under the [MIT License](LICENSE.md). Feel free to modify and use it according to your needs.
2. Navigate to the `Periphery` tree in the structure view.

<br />
3. Right-click on the `Virtual Inputs` and select `Add Virtual UDP Input`.

[![SonarCloud](https://sonarcloud.io/images/project_badges/sonarcloud-black.svg)](https://sonarcloud.io/summary/new_code?id=marcelschreiner_hue-to-loxone)
4. In the properties of the newly created Virtual UDP Input, set the `UDP Command` to for exaple `hue_event/sensors/42/\v`.
<br/><br/>

## License
Released under the [MIT License](LICENSE.md), this code is yours to command! 🚀 Modify it, tweak it, use it to your heart's content. Let's create something amazing together! 💻🌟
2 changes: 1 addition & 1 deletion get_api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ async def main():
try:
api_key = await create_app_key(HUE_IP, "authentication_example")
print("Authentication succeeded, api key: ", api_key)
print("NOTE: Add hue_app_key in main.py for next connections, it does not expire.")
print("NOTE: Add api key in hue2lox.py for next connections, it does not expire.")
except Exception as exc: # pylint: disable=broad-exception-caught
print("ERROR: ", str(exc))

Expand Down
3 changes: 2 additions & 1 deletion hue2lox.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def get_names():
for item_type in ["lights", "groups", "sensors"]:
for key, value in data[item_type].items():
names[f"/{item_type}/{key}"] = value["name"]
print(f"{item_type}/{key}: {value['name']}")

# Special addition for the group "0" which is all lights
names["/groups/0"] = "All lights"
Expand All @@ -93,7 +94,7 @@ async def main():
"""Main application"""
async with HueBridgeV2(HUE_IP, HUE_API_KEY) as bridge:
print("Connected to bridge: ", bridge.bridge_id)
print("Getting light names...")
print("Getting item names...")
get_names()
print("Subscribing to events...")
bridge.subscribe(parse_event)
Expand Down

0 comments on commit 0c280d1

Please sign in to comment.