1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Xiaomi RGB Bulb simple UDP server solution

Discussion in 'Hyperion Setup Showcase' started by navigonic, 10 December 2016.

  1. navigonic

    navigonic New Member

    Messages:
    9
    Hardware:
    RPi3
    So this is to use the RGB Bulb as a cheap ambilight:

    Set the mode as udp (new implementation is what I use)
    Set it up as 1 LED (use left or right), port 19446

    then set the ip to whatever computer can run this script:.

    You'll need to "pip install yeelight"

    The script/server:
    import socket
    import time
    from yeelight import *

    #UDP SERVER
    port = 19446
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind(("", port))
    print("waiting on port:", port)

    #YEELIGHT
    bulb = Bulb("BULB_IP_ADDRESS")
    bulb.turn_on()
    bulb.effect = "sudden"

    #Stop/Start music mode, bypasses lamp rate limits, ensures that previous sockets close before starting
    bulb.stop_music()
    time.sleep(1)
    bulb.start_music()
    time.sleep(1)

    while True:
    d = s.recvfrom(3)
    bulb.set_rgb(*bytearray(d[0]))
     
    Last edited: 10 December 2016
  2. penfold42

    penfold42 Moderator Developer

    Messages:
    740
    Hardware:
    RPi1/Zero, RPi2, RPi3, 32/64bit, +Arduino, +nodeMCU/ESP8266
    Cool!

    Thanks for sharing
     
  3. Squizzy

    Squizzy New Member

    Messages:
    18
    Hardware:
    RPi2
    EDIT: For me it is not working well. the color change is not reliable :( is it a timing problem? or a hardware limitation?


    Original Post:
    i ve got some Exception errors. i fixed it. dont know if this is a clean solution. but it works :p


    Code:
    #!/usr/bin/python
    
    import socket
    import time
    from yeelight import *
    
    #UDP SERVER
    port = 19446
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind(("", port))
    print("waiting on port:", port)
    
    #YEELIGHT
    bulb = Bulb("192.168.2.105")
    bulb.turn_on()
    bulb.effect = "sudden"
    
    #Stop/Start music mode, bypasses lamp rate limits, ensures that previous sockets close before starting
    while True:
        try:
            bulb.stop_music()
            break
        except BulbException:
            break
    time.sleep(1)
    while True:
        try:
            bulb.start_music()
            break
        except BulbException:
            break
    time.sleep(1)
    
    try:
        while True:
            d = s.recvfrom(3)
            bulb.set_rgb(*bytearray(d[0]))
    except KeyboardInterrupt:
        print "Exit ..."
     
    Last edited: 14 January 2017
  4. penfold42

    penfold42 Moderator Developer

    Messages:
    740
    Hardware:
    RPi1/Zero, RPi2, RPi3, 32/64bit, +Arduino, +nodeMCU/ESP8266
    Packet loss ?

    Is it udp to the light ?

    I'm assuming you py is running on the same box as Hyperion ? If so, almost no chance of packet loss there !

    Is hyperion flooding your py script with updates ?
     
  5. Reevee

    Reevee New Member

    Messages:
    1
    Hardware:
    RPi1/Zero, RPi2, RPi3
    I would really like to add the Yeelight to my Kodi setup with Hyperion. Do you have some kind of dummy manual to achieve this, because I don't know where to start.

    My situation is:
    • Running Libreelec on a Raspberry Pi
    • Hyperion runs on this Raspberry Pi with WS2801 leds
    • A separate Yeelight wifi Bulb
    • several Raspberry Pi's if necessary...
     
    • Like Like x 1
  6. nedir

    nedir New Member

    Messages:
    1
    Hardware:
    RPi1/Zero, RPi2

    Hello Squizzy,

    You can probe if is a hardware limitation if you add this line into a loop:

    echo -ne '{"id":1,"method":"set_rgb","params":[255, "sudden", 0]}\r\n' |nc -w1 192.168.168.100 112233

    With this you send directly a command to yeelight, and changin the "255" you can change the color.

    I doesn't have yeelight bulb, but if anyone probe that is possible the rate of color change's, I buy one.
     
  7. lemonCMS

    lemonCMS New Member

    Messages:
    1
    Hardware:
    RPi3, +Arduino, +nodeMCU/ESP8266
    Hi, i just wanted to share my version of the python script.

    Code:
    #!/usr/bin/python
    
    import socket
    import time
    import math
    from yeelight import *
    
    ip_address = "192.168.178.131"
    timeout = 200
    
    def rgb2hsv(r, g, b):
        r, g, b = r/255.0, g/255.0, b/255.0
        mx = max(r, g, b)
        mn = min(r, g, b)
        df = mx-mn
        if mx == mn:
            h = 0
        elif mx == r:
            h = (60 * ((g-b)/df) + 360) % 360
        elif mx == g:
            h = (60 * ((b-r)/df) + 120) % 360
        elif mx == b:
            h = (60 * ((r-g)/df) + 240) % 360
        if mx == 0:
            s = 0
        else:
            s = df/mx
        v = mx
        return round(h), round(s * 100, 1), round(v * 100, 1)
    
    #UDP SERVER
    port = 19446
    last = ""
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind(("", port))
    print("waiting on port:", port)
    
    #YEELIGHT
    bulb = Bulb(ip_address, effect="smooth", duration=timeout)
    bulb.turn_on()
    status = "on";
    # bulb.effect = "smooth"
    
    #Stop/Start music mode, bypasses lamp rate limits, ensures that previous sockets close before starting
    while True:
        try:
            bulb.stop_music()
            break
        except BulbException:
            break
    time.sleep(1)
    while True:
        try:
            bulb.start_music()
            break
        except BulbException:
            break
    time.sleep(1)
    
    try:
        while True:
            d = s.recvfrom(3)
            new = bytearray(d[0])
            hsv = rgb2hsv(new[0], new[1], new[2])   
    
            if new != last:
                if hsv[2] == 0.0:
                    if status == "on":
                        bulb.turn_off()
                        status = "off"
                elif status == "off":
                    bulb = Bulb(ip_address, effect="smooth", duration=timeout)
                    while True:
                        try:
                            bulb.start_music()
                            break
                        except BulbException:
                            break
    
                    bulb.turn_on()
                    status = "on"
    
                if status == "on":
                    bulb.set_hsv(*hsv)
    
            last = new
    except KeyboardInterrupt:
        print("Exit ...")
    
     
    • Like Like x 2
  8. cmvac

    cmvac New Member

    Messages:
    22
    Hardware:
    RPi2, 32/64bit, Wetek
    Hi guys, are these smartbulbs working with Hyperion with the latest script? I am planning to buy some but want to be sure they work. And can we connect several, or is it limited in number? I have a Pi 3 and Hyperion, but I want, I have - i must ;):omg: - expand my hyperion setup to the rest of the living room.

    Also, I need to know how to run this script on the Pi. I know, noob question, but there are a lot of people with access to this forum who are not as versed in Python.

    In short: Do they work, can we use more than one and could we have a noob tutorial to run the script on our Pis?
     
  9. soulsick

    soulsick New Member

    Messages:
    6
    Hardware:
    RPi2
    Just completed the setup process. As I am also quite noobish, it took some time.

    The Yeelights work, you can use more than 1 (I got 2) and yes, i will try to do a tutorial.

    My setup: RPi2 with latest Raspbian, LED strip with 50 LEDs behind the TV and 2 Yeelight RGB bulbs. For this tutorial it is assumed you have your simple ambilight up and running (typically some sort of LED strip behind TV controlled by hyperion). It is also assumed that the python script is run on the same raspberry as hyperion. You may have to change the ports and IPs according to your network environment.

    Below the step-by-step tutorial:

    -Locate your hyperion folder where your config is. For me it's /etc/hyperion

    -Add as many hyperion configs as you have Yeelight RGB bulbs, use udp device (for each config a different port!):
    Code:
    "device" :
       {
         "name"  : "MyPiudp",
         "type"  : "udp",
         "output"  : "127.0.0.1:20450", "protocol" : 0,
         "rate"  : 1000000,
         "colorOrder" : "rgb"
       },
    -In each config, setup a single LED (example below is for my Yeelight which is to the left of the tv)
    Code:
    "leds" :
        [
            {
                "index" : 0,
                "hscan" : { "minimum" : 0.0000, "maximum" : 0.1000 },
                "vscan" : { "minimum" : 0.0000, "maximum" : 1.0000 }
            }
        ],
    -In each config, use different ports for the jsonServer and the protoSever and write them down as you will need them in the next step. Then you can add color transformation, smoothing etc. You don't need grabbers in your yeelight configs, because they will use the grabber of your "main" config.

    -In your main config, add forwarder for json and proto. Example below is for two yeelight configs.
    Code:
        "forwarder" :
        {
        "json" : [ "127.0.0.1:19450", "127.0.0.1:19452" ],
        "proto" : [ "127.0.0.1:19451", "127.0.0.1:19453" ]
        },
    -Add your configs to hyperion: Multiple Hyperion Instances

    -In the yeelight android app, activate LAN-control for each yeelight you want to use

    -Create a new python file, for example /home/pi/yee.py. I use the script by lemonCMS: Xiaomi RGB Bulb simple UDP server solution Pay attention to the port in the script. In my example you would have to use 20450.

    -Open a terminal and type
    Code:
    pip install yeelight
    -Start the python script by typing
    Code:
    python yee.py
    I think that's all you have to do. If you have any questions, feel free to ask.
     
    • Like Like x 2
  10. cmvac

    cmvac New Member

    Messages:
    22
    Hardware:
    RPi2, 32/64bit, Wetek
    Hi, I just got my two Yeelights, it took some time to get here from China ;). I am using LibreELEC with Hyperion. I know where the config file is - in the .config folder - but I am having trouble in finding the hyperion.service file. It is in a different folder then OSMC and Raspbian. Does anyone know where that file is in LibreELEC?
     
  11. cmvac

    cmvac New Member

    Messages:
    22
    Hardware:
    RPi2, 32/64bit, Wetek
    Houston, we have a problem: pip is not available in LibreELEC, I forgot that this OS is stripped of almost all Linux shell commands. I am not a newbie, but I never really had to fiddle with that before. Does anybody know any alternative way to get this to work with LibreELEC? Or do I need to scrap my LibreELEC system and start fresh with OSMC or Raspbian?
     
  12. cmvac

    cmvac New Member

    Messages:
    22
    Hardware:
    RPi2, 32/64bit, Wetek
    I've been fidling with the YeeMee addon for Kodi (https://forum.kodi.tv/showthread.php?tid=313197&pid=2687134#pid2687134) but it has (at least for me) a huge lag. Is there any lag with Hyperion and the Yeelights? I need to know this before I scratch my LibreELEC instalation and install Raspbian.

    Also, would there be any wiz who could port this to LibreELEC, for all of us who use that OS? I really don't use or need Raspbian. It would really be amazing to have these cool and cheap lights working with all Hyperion compatible systems.
     
  13. soulsick

    soulsick New Member

    Messages:
    6
    Hardware:
    RPi2
    As the Yeelights use WLAN, the lag is larger than driving an ambilight by wire over the gpio pins of a RPi. For me the lag is far from huge, but its slightly noticeable. Of course the lag depends on your network conditions and the hyperion config (smoothing etc) you use.

    Can't help with the LibreELEC issue. I use Raspbian (with Kodi) because i need a full-featured OS.
     
  14. pattyland

    pattyland New Member

    Messages:
    3
    Hardware:
    RPi3
    Thanks for thw work lemonCMS and soulsick. Somebody should make good wiki article out of it ;)
    Quick question: Why is black on my TV white on my yeelight? All other colors are working great!
     
  15. soulsick

    soulsick New Member

    Messages:
    6
    Hardware:
    RPi2
    Check your config. In the color transform block, there should be an option for "blacklevel" for each color (red, green, blue). Insert
    Code:
    "blacklevel" : 0.0000,
    for each color, that should result in black.
     
    • Like Like x 2
  16. pattyland

    pattyland New Member

    Messages:
    3
    Hardware:
    RPi3
    Thanks, I didn't copy the transform block from my main config. The gamma values fixed the problem for me! Quick demo:


    I asked lemonCMS to add the code to his Github Account: https://github.com/lemonCMS/hyperion_udp_yeelight
    Could be good place to submit pull requests :)
     
    Last edited: 13 January 2018
    • Like Like x 2
  17. diddydave

    diddydave New Member

    Messages:
    6
    Hardware:
    RPi3
    That looks awesome, now I have to try it out. Have some spare lights. Where did you get the globe type fitting from?
     
  18. pattyland

    pattyland New Member

    Messages:
    3
    Hardware:
    RPi3
    That's Fado from Ikea, 10€
     
    • Thank you Thank you x 1
  19. cmvac

    cmvac New Member

    Messages:
    22
    Hardware:
    RPi2, 32/64bit, Wetek

    So, I gave up on LibreELEC, and installed this with Pipplware (http://pipplware.pplware.pt). It all went fine until I got to the "python yee.py" part. I get the following error:

    [email protected]:~ $ python yee.py
    ('waiting on port:', 19450)
    Traceback (most recent call last):
    File "yee.py", line 40, in <module>
    bulb.turn_on()
    File "<decorator-gen-7>", line 2, in turn_on
    File "/usr/local/lib/python2.7/dist-packages/yeelight/main.py", line 53, in _command
    result = self.send_command(method, params).get("result", [])
    File "/usr/local/lib/python2.7/dist-packages/yeelight/main.py", line 277, in send_command
    raise_from(BulbException('A socket error occurred when sending the command.'), ex)
    File "/usr/local/lib/python2.7/dist-packages/future/utils/__init__.py", line 4
    54, in raise_from
    raise e
    yeelight.main.BulbException: A socket error occurred when sending the command.

    The UDP port is 20450, as you advised. What am I getting wrong?
     
  20. soulsick

    soulsick New Member

    Messages:
    6
    Hardware:
    RPi2
    Maybe you forgot to open the developer mode on your yeelight bulb? Get the yeelight android app and activate "LAN-Control".