Open Mushoz opened 3 years ago
This is correct. Typically, we would advise using host networking mode to avoid this issue. The yeelight api documentation specifically state to use multicast to try to find the bulbs, so that is the way that has been implemented. If you have a better way to avoid this issue, please let us know
I have been thinking on this issue for a while. Using host networking is definitely the easiest solution, but while Docker is great for ease of deployment, it's also a great tool for increasing security over simply running all applications directly on the Host. Sharing the same network space as the host definitely decreases the security aspect.
I have also been thinking of fixing this issue with some "smart" networking, by increasing the TTL of the multicast packets and proxying or routing the multicast traffic from the docker interface to the host's physical interface, but it has some major drawbacks:
From what I understand on how some other lights from other manufacturers are found (which also showed up in tcpdump), is by simply getting the IP from the host in the environment variable and then by simply sending 255 messages to a known port of said lights to all 255 different addresses in the current subnet. This means that this code to do so is already there, and could be reused. Yeelights are reachable by telnet on port 55443, so trying to connect on that port on all 255 address in the current subnet should do the trick. While the discovery protocol is definitely neater, as it also immediately returns current values of the light bulb, there's nothing an initial "get_prop" call won't be able to fetch.
It's definitely not as clean as the current implementation IMO, but it would allow the program to work in container mode as well. I'd understand if this is something you'd rather not implement, since it's not as clean. But in that case it might be worthwhile to include some information in the docs that Yeelights are not supported in container mode.
For many of the protocols that we currently have, diyhue uses nmap to do a scan of ip addresses within a subnet. I'll have to review the documentation again for how yeelights work, however if we can directly attempt communication with the bulb (which I assume we can), that would be a potential solution for this.
I am pretty sure you already have this, but if not, here's the link to the documentation where I got my information from: https://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf
Thank you very much for looking into a potential solution!
A fix for this likely won't be implemented for a while since there are other pressing issues. In the meantime, I believe you can switch back to bridge mode after the lights have been discovered so if you wish to avoid using host networking, that is an option.
I managed to find a workout by using a macvlan. This should be possible to setup via docker itself, but I prefer to run my containers via docker-compose. Below is the docker-compose file I am using to set up this container on its own IP in the same subnet as the rest of the network, which means the container is able to find the lights just fine, while still being isolated from the docker host:
version: '2.1'
services:
diyhue:
image: diyhue/core:latest
restart: always
container_name: diyhue
volumes:
- ./data:/opt/hue-emulator/export/
stdin_open: true
tty: true
stop_grace_period: 1m
networks:
- diyhue_macvlan
networks:
diyhue_macvlan:
driver: macvlan
driver_opts:
parent: eth0
ipam:
driver: default
config:
- subnet: 192.168.2.0/24
gateway: 192.168.2.1
It's a bit more complicated than a regular setup, but works as a nice workaround for now :)
In that case, it's still not isolated by the docker network driver. It still has access to the entire network, just not on the hosts networking. It's pretty similar there.
It is not a pretty solution but as a bypass you can the lightbulb as a manual configuration. If you don't want to think about how to set this up I advise to clone the repository and do the following:
sudo mkdir -p /opt/hue-emulator
sudo chown $USER /opt/hue-emulator
git clone https://github.com/diyhue/diyHue.git
cd diyHue
git checkout beta
pip install -r requirements
cd BridgeEmulator
python3
>>> from lights import discover
>>> discover.scanForLights()
>>> exit()
cat /opt/hue-emulator/config/lights.yaml
This will create a config for you which you can subsequently copy to the docker volume (which you should bind
in that case). The lights.yaml
will look this (you could also immediately add such a configuration):
'1':
id_v2: eaf1ab4d-9e64-4fff-8f4c-ab7c9fc09180
name: Yeelight color 178
modelid: LCT015
uniqueid: 00:17:88:01:00:c7:fe:34-0b
state:
'on': false
bri: 200
hue: 0
sat: 0
xy:
- 0.0
- 0.0
ct: 461
alert: none
mode: homeautomation
effect: none
colormode: ct
reachable: true
config:
archetype: sultanbulb
function: mixed
direction: omnidirectional
startup:
mode: safety
configured: true
protocol: yeelight
protocol_cfg:
ip: 192.168.178.178
id: '0x0000000007d46377'
backlight: false
model: color
Describe the bug When running diyHue inside a container with bridge networking, Yeelights cannot be found. Using TCPdump, it is clear that discovery happens via multicast at 239.255.255.250. However, this multicast traffic only reaches the docker host and does NOT get forwarded to the host's LAN network where the lights reside.
Steps to Reproduce
Expected behavior
Logs There aren't any errors in the logs, since everything is working as expected on diyHue's side. The multicast discovery packets simply never reach the Yeelights.
Docker Info (please complete the following information):
Checklist
Additional context N/A