sidoh / esp8266_milight_hub

Replacement for a Milight/LimitlessLED hub hosted on an ESP8266
MIT License
935 stars 220 forks source link

Group state coupling - multiple remotes #198

Open starkillerOG opened 6 years ago

starkillerOG commented 6 years ago

I have my main ceiling milight lights coupled to multiple remotes with diffrent ID's. Using some automations I have coupled all those ID's to the same "bulb" in Home Assistant. The basics of this works verry well and the state in Home Assistant is tracked whatever remote is used.

However certain situations cause problems, for instance: If the milight light is turned OFF with remote A, then later turned ON with remote B, and then again later the color is changed with remote A, Home assistant will think that the bulb is OFF while in fact the bulb is ON at some color. This is because the state of remote A is still OFF and was never turend "ON" only the color is changed. This is anoying for keeping track of the state of the bulb.

My proposed solution is to have an option in the ESP Milight Hub to couple two groups of two diffrent ID's to always have the same state. So if the state of A changes the state of B is also updated. This would be awesom to have correct tracking of the states in third pary applications such as Home Assistant when using multiple remotes.

I have no idea how hard this would be? Does anyone have time to look into this?

sidoh commented 6 years ago

Neat idea. I'm a little hesitant to add complexity to state handling. There's already more weight to it than I'd like.

Are you able to use different groups with the same device ID? You could use group 0 to control all groups with the same device ID. State updates pushed to group 0 are propagated to groups 1-N as you'd expect.

One suggestion I might have is to pair your bulbs with a virtual device ID, and set up an automation in HASS to forward commands from both remotes to the virtual device ID. Here's a writeup on how to set that up:

https://github.com/sidoh/esp8266_milight_hub/wiki/Using-Milight-Remote-with-HomeAssistant

This is essentially the same thing, but the coupling logic is in HASS instead of espMH, which feels a little nicer to me. I'd like to keep espMH as thin as is possible.

starkillerOG commented 6 years ago

Unfortunately I am not able to chose the device ID, I use two diffrent physical milight remotes (B8 wall panel and RGBW remote FUT096) that have the device ID build in. As far as I am aware you can not alter that device ID.

In principle using a virtual device ID would probably work, however I have now paired the milight remotes directly to the light. Using a virtual device ID a lot more devices would be involved; my ESPMH would need to receive the signal, sent it to my MQTT broker on anouter device through my router, to HASS and then back to the MQTT broker then back to ESPMH and then the ESPMH needs to sent a signal to the bulb. Therefore if one of my devices fails due to some reason such as me messing with HASS I would be unable to switch my lights. If I use direct control from the remotes and use ESPMH only to update the states, I will always be able to switch my lights and I will only lose automation and state tracking capabilities if I am messing around again with my system. Furthermore in my experiance the milight remotes respond a little faster when using direct control (if fast switching between colors) and is slightly more reliabel.

Therefore to keep the system as robust as possible I prefer to use direct control where possible. (I do use the virtual device ID exactly as you suggest to control incompatible bulbs such as my dual white bulb with my B8 panel.)

Furthermore I also use a significant amount of milight groups to control third party lights such as hyperion lights or RF wall plugs. For those lights I only use the MQTT delta update to receive the signals from the milight remotes and further parsing and control is done in seprate programs. Therefore resources spent on keeping the state of these groups is wasted because I do not use the full MQTT update. If state keeping ideed costs a lot of resources it might be worthwhile to have an option to disable state keeping per group.

What I am missing in ESPMH is control over the state keeping. In my opinion it would be greath to have the ability to disable state keeping for groups that are not used and have an option to couple diffrent groups to be able to use multiple remotes (in direct control) and still keep the state correct.

sidoh commented 6 years ago

Fair enough.

The complexity I'm referring to is in the code. I don't think it actually contributes a ton to performance, but that's a concern too. Actually think adding more branches and lookups to the code would hurt performance more than the skipping would help. Might be good to skip MQTT updates for some topics, but that's about it.

Might make sense to do this, but I think there are other things I'd work on first.

If you're looking for short-term solution that doesn't reduce robustness of your setup, perhaps you could pair the bulbs with your remotes and the virtual device ID? This would probably be screwy for relative commands like "mode speed up," but should work fine for absolute commands like "brightness to 50%."

starkillerOG commented 6 years ago

Thanks for the tips!

Would be greath if this could be fixed in a future release. If I can help with anything, just sent me a message.

oakbrad commented 6 years ago

@starkillerOG You can accomplish this with Node-Red. Just route payloads from the remote to your desired MQTT light topic. This is how I have my multiple remotes set up.

sidoh commented 6 years ago

Great suggestion @oakbrad. I've been playing around with Node-RED over the last week or so and have been really impressed. I think I'll create a wiki page for doing this kind of stuff with Node-RED at some point.

starkillerOG commented 6 years ago

@oakbrad cool, could you explain how you menaged to do this? I have set up forwarding of the MQTT messages from all the remotes to one topic so I receive all the messages (using automations in Home Assistant). However I am experiencing troubles with that as explained in the original post due to the messages itself containing incorrect information due to certain states beeing wrong in memory because they don't get the history from the other remotes.

Do you do any proccesing of the messages in Node-RED or do you only forward the messages?

devax commented 6 years ago

Just to add a comment for those who want to do simple message forwarding in MQTT. If your MQTT broker is Mosquitto, you can also configure Mosquitto to run in bridge mode. In bridge mode, Mosquitto will forward messages from one topic to another topic. Most tutorials describe it as an inter-broker setup, but it works very well on a single instance too. That way your setup will not depend on an additional Node Red instance.

PatrickTheTechGuy commented 6 years ago

@devax Could you add instructions on how you did that?

devax commented 6 years ago

I more or less followed this instruction here: http://www.steves-internet-guide.com/mosquitto-bridge-configuration/2

Here is a sample configuration you could add to your mosquitto.conf. This would forward every message posted to id 0x1111 to id 0x2222 and vice versa. Instead of both you can also use in or out. (both = in + out). Also, you can add multiple lines starting with "topic", if necessary. Note that the mosquitto server specified on the "address" can be your local mosquitto server for simple topic forwarding on your local mosquitto server.

connection milightworkaround
address mymosquittoservername:1883
topic # both 0 milight/states/0x1111/fut089/ milight/states/0x2222/fut089/
remote_clientid localbridgeremote
local_clientid localbridgelocal
remote_username myusername
remote_password mypassword

Hope that makes sense.

PatrickTheTechGuy commented 6 years ago

@devax I got it to work! Thanks!

fermentfan commented 5 years ago

I have my main ceiling milight lights coupled to multiple remotes with diffrent ID's.

@starkillerOG could you elaborate on how you achieved that? Are there special Milight bulbs that support this? I thought you can only link it to one id.

starkillerOG commented 5 years ago

@DennisVonDerBey I have read some documentation one time that explained that you can couple up to 5 remote ID's to the same bulb after wich it will forget the first ID if you couple a 6th ID. Note that this is just out of the top of my head, I searched but cann't find that documentation anymore.

Coupeling to multiple ID's is verry simple, just couple the bulb to the first ID by cutting power to it, then turn on the power and at the same time hold the ON button on the remote of the group that you want to couple. Once it couples correctly. just cut the power again to the bulb, turn the power back on and now couple to the second remote with the group that you want. Just keep repeating this for all the ID's you want to couple the bulb to.

For me this has worked for all of my bulb types, E27 RGBW: FUT016, GU10: FUT103, E27 CCT: FUT019. Hope this helps.

Brignoud commented 5 years ago

(I do use the virtual device ID exactly as you suggest to control incompatible bulbs such as my dual white bulb with my B8 panel.)

Please, @starkillerOG how do you accomplish that state above? Me too have a B8 wall remote controller and a dozen of Dual White incompatible bulbs that would be fine to managed with only one central remote

By the way, I'm using OpenHab for my automation and notice can managed your problem differently, simply by assignging the same "ITEM" to all of your THINGS (the remote IDs assigned point, say the group button)

starkillerOG commented 5 years ago

@Brignoud I actually ended up writing 2 python scripts that are permenantly running on my rasbperry Pi3 (the same that is also running HomeAssistant in my case). I called them "MilightForwarder.py" and "MilightControl.py". Both scripts are subscribed to the mqtt_update_topic.

The "MilightControl.py" scipt is doing what you are looking for, it bassically just takes the messages received from physical remotes and then parses them and forwards them to diffrent kind of platforms. The simplest one beeing just forward to an diffrent mqtt topic to let the esp_milight_hub control an bulb that is otherwise incompatible with the physical remote. This can in principle also be done with simple automations in homeassistant that forward the messages, but you would end up with a thon of automations instead of one simply configurable and expandable python script. Furtermore, I also use this script to parse the milight messages to control other platforms like Hyperion that use json http rest messages, or control RF wall plugs (with some other ESP bridge).

The "MilightForwarder.py" script takes all the mqtt_update messages from the ESP milight hub and then uses its memory of previous received commands and a fair bit of logic to forward the state of my bulbs to another mqtt topic. I build this before ESP milight hub was capable of tracking states. But the reason that I am still using it is because I am also able to have multiple Device ID's coupled to one bulb and do some advanced logic to keep track of the state of that bulb. For instance, my ceiling light consists of 3 bulbs that I control with a Device ID (main_light) coupled to all the bulbs to change the whole lamp at once, but I also have Device ID's (sub_lights) to control individual bulbs whithin the same light. Therefore if I turn on the main_light all sub_lights schould also update their state (taking into acount things like the current state of those sub_lights such as power ON/OFF or color/white mode). This would not be possible with simple automations because you need to take into account the current state of all the sub_lights in order to determine if the command that was sent will apply to that sub_light or not (for instance sending a brightness command while only 2 of the 3 sublights are turned ON).

Hope you can follow me a bit @Brignoud. I could post the 2 mentioned python scripts if you want to @Brignoud?

Brignoud commented 5 years ago

@starkillerOG Thanks, many thanks This sound like I was supposed to be this nice workaround It would be nice to see this just implemented in the Hub itself but you're right this implementations is so usefull in several other and different situations

So yes, please, publish the two Phyton scripts, and I will be so gratefull (with other people I think :-) )

starkillerOG commented 5 years ago

@Brignoud I just made a new github project where I posted the two scripts. MiligthControl.py and MilightForwarder.py. This is the link to the project.

I did not have time to write a complete discription or settings guide. Feel free to ask anything about the scripts, or if you have trouble setting it up. I would gladly help you with the settings.

Brignoud commented 5 years ago

Thanks @starkillerOG , trying to implement on my side even if I'm running the bind with Openhab instead of Home assistant and also verifying if it possibile to install all the requirements via pip on my Openhabian instance

Brignoud commented 5 years ago

Hi @starkillerOG , As I said, I'm running OPENHAB on Openhabiian distro So I wonder if phyton 2 is already set on board and don't know exactly how to verify since phyton -V seem to return no usefull information I understood I can place your two scripts under OPENHAB installation and got no problem to do this but didn't fully understand the meaning of "Import modules" and how to download and upload them to my system if necessary Thank you friend

starkillerOG commented 5 years ago

@Brignoud, "Import modules" are just the python modules that are used in my scipt. For "MilightForwarder.py" they are:

import sys
import json
import ast
import colorsys
import paho.mqtt.client as mqtt
import yaml

For "MilightForwarder.py" they are:

import socket
import sys
import paho.mqtt.client as mqtt
import colorsys
import json
import ast
import yaml

You can check if a module is installed by running this in the command line: pip show [module name] For colorsys it would be: pip show colorsys It will give you information about the module such as the installation directory and the version of the module installed.

You can install modules using pip, for instance: pip install colorsys

Or you can just run my python script from command line and see if you get an import module error, if not, you have all modules installed, otherwise the error will specify wich module is missing.