Skip to content

Commit

Permalink
[espmilighthub] Initial contribution (#9218)
Browse files Browse the repository at this point in the history
* espmilighthub inital

Signed-off-by: Matthew Skinner <matt@pcmus.com>

Co-authored-by: Fabian Wolter <github@fabian-wolter.de>
Co-authored-by: Connor Petty <mistercpp2000+gitsignoff@gmail.com>
  • Loading branch information
3 people authored Jan 29, 2021
1 parent 80c52f4 commit b2bb917
Show file tree
Hide file tree
Showing 17 changed files with 1,244 additions and 1 deletion.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
/bundles/org.openhab.binding.monopriceaudio/ @mlobstein
/bundles/org.openhab.binding.mpd/ @stefanroellin
/bundles/org.openhab.binding.mqtt/ @davidgraeff
/bundles/org.openhab.binding.mqtt.espmilighthub/ @Skinah
/bundles/org.openhab.binding.mqtt.generic/ @davidgraeff
/bundles/org.openhab.binding.mqtt.homeassistant/ @davidgraeff
/bundles/org.openhab.binding.mqtt.homie/ @davidgraeff
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,11 @@
<artifactId>org.openhab.binding.mqtt</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.mqtt.espmilighthub</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.mqtt.generic</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.mqtt.espmilighthub/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons
193 changes: 193 additions & 0 deletions bundles/org.openhab.binding.mqtt.espmilighthub/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# EspMilightHub Binding

This binding allows an open source esp8266 based bridge to automatically find and add Milight globes.
The hubs can be built from 2 ready made boards and only need connecting with 7 wires.
They can be very easy to build with no soldering needed.

Advantages to using this DIY bridge over the OEM bridge:

+ Almost unlimited groups to give individual control over an entire house of Milight globes without needing multiple bridges.
+ If using the Milight remotes to control the globes, this binding can update the openHAB controls the moment a key is pressed on the physical remotes.
+ Supports auto discovery.

## Setup the hardware

In depth details on how to build and what the bridge is can be found here: <http://blog.christophermullins.com/2017/02/11/milight-wifi-gateway-emulator-on-an-esp8266>

A quick overview of the steps to get the hardware going are:

+ Connect a nodemcu/D1 mini/esp8266 to your computer via a USB cable.
+ Download the latest BIN file from here <https://github.com/sidoh/esp8266_milight_hub/releases>
+ Download esp8266flasher if you are on windows <https://github.com/nodemcu/nodemcu-flasher>
+ Check the blog above on more info for Mac or Linux.
+ Open the flasher tool and make sure the flash size is 4mb or whatever your esp8266 board has.
+ Flash the bin and press the reset button on the board when it completes.
+ Connect to the wifi access point of the esp directly with your phone/tablet and setup wifi details.
+ Login by using the IP address of the esp8266 in a web browser and the control panel will show up.
+ Connect 7 wires between the two ready made PCBs as shown in the blog.
+ Setup a MQTT broker as this method uses the faster and lightweight MQTT protocol and not UDP.

## Setup the Firmware

Enter the control panel for the ESP8266 by using any browser and enter the IP address.
The following options need to be changed in the firmware for the binding to work.
Click on SETTINGS>MQTT>:

**mqtt_topic_pattern:**
`milight/commands/:device_id/:device_type/:group_id`

**mqtt_update_topic_pattern:**
Leave this blank.

**mqtt_state_topic_pattern:**
`milight/states/:device_id/:device_type/:group_id`

**group_state_fields:**
IMPORTANT: Make sure only the following are ticked:

+ state
+ level
+ hue
+ saturation
+ mode
+ color_temp
+ bulb_mode

Fill in the MQTT broker fields with the correct details so the hub can connect and then click **save**.
Now when you use any Milight remote control, you will see MQTT topics being created that should include `level` and `hsb` in the messages.
If you see `brightness` and not `level`, then go back and follow the above setup steps.

You can use this Linux command to watch all MQTT topics from Milight:

```
mosquitto_sub -u usernamehere -P passwordhere -p 1883 -v -t 'milight/#'
```

You can also use the mosquitto_pub command to send your own commands and watch the bulbs respond all without the binding being setup.
Everything this binding does goes in and out via MQTT and can be watched with the above command.
Once you have setup and test the hub you can move onto using the binding.

## Supported Things

This binding is best thought of as a remote control emulator, so the things are really the type of remote that you own and not the globes.
The Milight protocol is 1 way only so there is no way to find actual globes.

| Thing Type ID | Description |
|-|-|
| `rgb_cct` | Remote that has 4 channels and controls globes with full colour, and both cool and warm whites. |
| `fut089` | Remote is the newer 8 channel type called FUT089 and your globes are the rgb_cct. |
| `cct` | Remote is 4 channels and the globes have no colours with only cool and warm white controls. |
| `fut091` | Remote is the newer 8 group model called a fut091 and your globes are cct. |
| `rgbw` | Remote is 4 channels and the globes have RGB and a fixed white. |
| `rgb` | Remote is 4 channels and the globes have full RGB with no white. |

## Discovery

First install the MQTT binding and setup a `broker` thing and make sure it is ONLINE, as this binding uses the MQTT binding to talk to your broker and hence that binding must be setup first.
Next, move a control on either a physical remote, or used a virtual control inside the esp8266 control panel web page which cause a MQTT message to be sent.
This binding should then detect the new device the moment the control is moved and a new entry should appear in your INBOX.

To remove a saved state from your MQTT broker that causes an entry in your INBOX you can use this command or use the ignore feature of openHAB.

```
mosquitto_pub -u username -P password -p 1883 -t 'milight/states/0x0/rgb_cct/1' -n -r
```

## Thing Configuration

| Parameter | Description | Required | Default |
|-|-|-|-|
| `whiteHue` | When both the `whiteHue` and `whiteSat` values are seen by the binding it will trigger the white LEDS. Set to -1 to disable, 0 for Alexa, or 35 for Google Home. | Y | 35 |
| `whiteSat` | When both the whiteHue and whiteSat values are seen by the binding it will trigger the white LEDS. Set to -1 to disable, 100 for Alexa or 32 for Google Home. | Y | 32 |
| `favouriteWhite` | When one of the shortcuts triggers white mode, use this for the colour white instead of the default colour. | Y |200 |
| `dimmedCT` | Traditional globes grow warmer the more they are dimmed. Set this to 370, or leave blank to disable. | N | blank |
| `oneTriggersNightMode` | Night mode is a much lower level of light and this feature allows it to be auto selected when your fader/slider moves to 1%. NOTE: Night mode by design locks out some controls of a physical remote, so this feature is disabled by default. | Y | false |
| `powerFailsToMinimum` | If lights loose power from the power switch OR a power outage, they will default to using the lowest brightness if the light was turned off before the power failure occurred. | Y | true |
| `whiteThreshold` | RGBW globes do not respond to saturation changes, so this feature allows you to specify a number that if the saturation drops below, it will trigger the white mode. -1 will disable this feature. | Y | 12 |

## Channels

| Channel | Type | Description |
|-|-|-|
| `level` | Dimmer | Level changes the brightness of the globe. |
| `colourTemperature` | Dimmer | Change from cool to warm white with this control. |
| `colour` | Color | Allows you to change the colour, brightness and saturation of the globe. |
| `discoMode` | String | Switch to a Disco mode directly from a drop down list. |
| `bulbMode` | String (read only) | Displays the mode the bulb is currently in so that rules can determine if the globe is white, a color, disco modes or night mode are selected. |
| `command` | String | Sends the raw commands that the buttons on a remote send. |

## Note Regarding Transmission Delays

If you have lots of globes and openHAB turns them all on, you may notice a delay that causes the globes to turn on one by one and the delay can add up when a lot of globes are installed in your house.
This is caused by the time it takes to transmit the desired setting to the globe multiplied by how many times the hub repeats transmitting the setting.
Since it takes around 2.8ms for a setting to be transmitted, if the firmware is set to repeat the packets 50 times it would then take 2.8*50 = 140ms before the next globe starts to have its new state transmitted by the hub.
You can reduce the packet repeats to speed up the response of this binding and the hub by tweaking a few settings.

Settings can be found on the radio tab in the esp control panel using your browser.
Suggested settings are as follows:

+ Packet repeats = 12 (if you only turn 1 globe on or off it uses this value)
+ Packet repeat throttle threshold = 200
+ Packet repeat throttle sensitivity = 0
+ Packet repeat minimum = 8 (When turning multiple globes on and off it will use this value as it throttles the repeats back to reduce latency/delay between each globe)

## Important for Textual Configuration

This binding requires things to have a specific format for the unique ID, the auto discovery does this for you.

If doing textual configuration you need to add the Device ID and Group ID together to create the things unique ID.
The DeviceID is different for each remote.
The GroupID can be 0 (all channels on the remote), or 1 to 8 for each of the individual channels on the remote).
If you do not understand this please use auto discovery to do it for you.

The formula is
DeviceID + GroupID = ThingUID

For example:

| Device ID | Group ID |ThingUID |
|-----------|----------|----------|
| 0xE6C | 4 | 0xE6C4 |
| 0xB4CA | 4 | 0xB4CA4 |
| 0xB4CA | 8 | 0xB4CA8 |
| 0xB4CA | 0 | 0xB4CA0 |

## Full Example

To use these examples for textual configuration, you must already have a configured a MQTT `broker` thing and know its unique ID.
This UID will be used in the things file and will replace the text `myBroker`.
The first line in the things file will create a `broker` thing and this can be removed if you have already setup a broker in another file or via the UI already.

*.things

```
Bridge mqtt:broker:myBroker [ host="localhost", secure=false, password="*******", qos=1, username="user"]
Thing mqtt:rgb_cct:0xE6C4 "Hallway" (mqtt:broker:myBroker) @ "MQTT"
```

*.items

```
Dimmer Hallway_Level "Front Hall" {channel="mqtt:rgb_cct:0xE6C4:level"}
Dimmer Hallway_ColourTemperature "White Color Temp" {channel="mqtt:rgb_cct:0xE6C4:colourTemperature"}
Color Hallway_Colour "Front Hall" ["Lighting"] {channel="mqtt:rgb_cct:0xE6C4:colour"}
String Hallway_DiscoMode "Disco Mode" {channel="mqtt:rgb_cct:0xE6C4:discoMode"}
String Hallway_BulbCommand "Send Command" {channel="mqtt:rgb_cct:0xE6C4:command"}
String Hallway_BulbMode "Bulb Mode" {channel="mqtt:rgb_cct:0xE6C4:bulbMode"}
```

*.sitemap

```
Text label="Hallway" icon="light"
{
Switch item=Hallway_Level
Slider item=Hallway_Level
Slider item=Hallway_ColourTemperature
Colorpicker item=Hallway_Colour
Selection item=Hallway_DiscoMode
Text item=Hallway_BulbMode
Switch item=Hallway_BulbCommand mappings=[next_mode='Mode +', previous_mode='Mode -', mode_speed_up='Speed +', mode_speed_down='Speed -', set_white='White', night_mode='Night' ]
}
```
24 changes: 24 additions & 0 deletions bundles/org.openhab.binding.mqtt.espmilighthub/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>3.1.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.mqtt.espmilighthub</artifactId>
<name>openHAB Add-ons :: Bundles :: MQTT EspMilightHub</name>

<dependencies>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.mqtt</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.mqtt.espmilighthub-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-binding-mqtt-espmilighthub" description="MQTT Binding EspMilightHub" version="${project.version}">
<feature>openhab-runtime-base</feature>
<feature>openhab-transport-mqtt</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt/${project.version}</bundle>
<bundle start-level="81">mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt.espmilighthub/${project.version}</bundle>
</feature>

</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.mqtt.espmilighthub.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* The {@link ConfigOptions} Holds the config for the settings.
*
* @author Matthew Skinner - Initial contribution
*/
@NonNullByDefault
public class ConfigOptions {
public int whiteThreshold = -1;
public int whiteSat = 32;
public int whiteHue = 35;
public int favouriteWhite = 200;
public boolean oneTriggersNightMode = false;
public boolean powerFailsToMinimum = false;
public int dimmedCT = -1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/

package org.openhab.binding.mqtt.espmilighthub.internal;

import static org.openhab.binding.mqtt.MqttBindingConstants.BINDING_ID;

import java.math.BigDecimal;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;

/**
* The {@link EspMilightHubBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Matthew Skinner - Initial contribution
*/
@NonNullByDefault
public class EspMilightHubBindingConstants {
public static final String STATES_BASE_TOPIC = "milight/states/";
public static final String COMMANDS_BASE_TOPIC = "milight/commands/";
public static final BigDecimal BIG_DECIMAL_100 = new BigDecimal(100);
// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_RGB_CCT = new ThingTypeUID(BINDING_ID, "rgb_cct");
public static final ThingTypeUID THING_TYPE_CCT = new ThingTypeUID(BINDING_ID, "cct");
public static final ThingTypeUID THING_TYPE_RGBW = new ThingTypeUID(BINDING_ID, "rgbw");
public static final ThingTypeUID THING_TYPE_RGB = new ThingTypeUID(BINDING_ID, "rgb");
public static final ThingTypeUID THING_TYPE_FUT089 = new ThingTypeUID(BINDING_ID, "fut089");
public static final ThingTypeUID THING_TYPE_FUT091 = new ThingTypeUID(BINDING_ID, "fut091");

public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_RGBW, THING_TYPE_RGB_CCT,
THING_TYPE_FUT089, THING_TYPE_FUT091, THING_TYPE_CCT, THING_TYPE_RGB);

// Channels
public static final String CHANNEL_LEVEL = "level";
public static final String CHANNEL_COLOUR = "colour";
public static final String CHANNEL_COLOURTEMP = "colourTemperature";
public static final String CHANNEL_DISCO_MODE = "discoMode";
public static final String CHANNEL_BULB_MODE = "bulbMode";
public static final String CHANNEL_COMMAND = "command";
}
Loading

0 comments on commit b2bb917

Please sign in to comment.