Mi-Light controller for Mysensors



  • MiLight is a radio controlled RGB-W LED light bulb. You can buy them from ebay or aliexpress for about $10-$15 a piece. The light bulb is controlled by a handheld controller. The RF chip used in these lights are PL1167 but fortunately, people have reverse engineered the RF protocol (see https://hackaday.io/project/5888-reverse-engineering-the-milight-on-air-protocol) and have developed code to control these lights using a NRF24 radio.

    I have adapted these code to control these light bulbs using a mysensors module, which also serves as a repeater node. Once it receives command from the gateway, it switches to a different operation mode to simulate PL1167 and send commands to control the LED bulb. Afterwards, the sensor switches back to NRF24 mode and serve as repeater.

    The code currently supports two modes of operation: (1) turn the white light on/off using a light switch node; and (2) relay any command that is supported by the MI protocol using a custom sensor node.
    You need to 'pair' the light bulb with the controller the first time using it (UPDATE: you can do the pairing using the repeater node. No need to buy a separate wifi or wireless controller). To do so, turn on the power switch and send 'on' command to the light bulb within couple of seconds. The led bulb will flash a couple of times if the paring is successful.

    If you have multiple LED lights, you can assign each light with the same or different remote ID so you can control them as a group or individually.

    The code can be downloaded here (also see below for required library):
    0_1460251721914_open_Mi_Light_Controller_repeater.zip


  • Admin

    Great!
    You should add this project (with a image) to openhardware.io so it becomes easier to find.



  • Wonderfull. I have a lot of milight bulbs and using openmili too. Your work is fantastic, I will try it when have little time.



  • can rgb bulbs also be controlled/set color/dim ?



  • @Cliff-Karlsson
    Yes, I can control RGB color as well. The node can relay any command from the gateway to the Mi Bulb. It can implement the full capability of the original remote controller. The format of the MI protocol can be found here: https://hackaday.io/project/5888-reverse-engineering-the-milight-on-air-protocol . The node receives the command as a ASCII string; it then convert it to HEX format and send it to the bulb.



  • i'm getting this error:

    [code]
    open_Mi_Light_Controller_repeater.ino:3:23: fatal error: nRF_24L01.h: No such file or directory
    compilation terminated.
    [/code]



  • oops. I forgot to attach the modified nrf24 library.
    Somehow the module that simulates PL1167 is not compatible with mysensors' nrf24 library; instead, it requires the nrf24 library found here: http://tmrh20.github.io/RF24 , which, strangely, is not compatible with mysensors. So I end up with using two different nrf24 libraries, one for mysensor and the other for simulating PL1167. To make this work, I have to change the variable/file names of one of the libraries. Maybe there is something I didn't do correctly. Anyway, if you import the following library, it should work. 0_1460766143691_RF_24-master.zip

    @koen01



  • I just ordered four 9w rgbww bulbs to try your script out. But when reading the reviews one of the main disadvantages I found where that it was not possible to query the bulbs for the current state/color/dim-level.
    But if the bulbs are wired so that they are always on then the script/repeater-node or the controller keep track of all the states, right?

    Also is it possible to connect an battery powered arduino/nrf to the existing non powered wall-switch and have the arduino to send the switch-commands directly to the mi-light-repeater-node for faster reaction times for turning the bulbs on/off?



  • @Cliff-Karlsson

    Yes, it is possible to keep track of the bulb state from the controller.

    As to the switching speed, it is almost instantaneous (<<1 s). You can for sure add another node, but that will make the whole thing much more complicated to build.



  • @ted

    Thanks, I forgot to ask but if the node(s) have the full capability as the original remote controler. That means that I can also control ledstrips using the mi-light led dimmers like this: Led controller right?



  • Assuming the on-air protocols are the same, yes.
    I only have the RGB-W light bulb and were able to control it without ever using the remote controller.
    @Cliff-Karlsson



  • @ted said:

    (1) turn the white light on/off using a light switch node

    What does this mean? do I connect a light switch to the repeater-node? Or does it just mean that I can use another arduino to detect button-switches and send command to domoticz or other controller?



  • I have received my lamps now but no controller yet. Is it possible to pair/control the bulbs without controller?



  • @Cliff-Karlsson
    To pair, turn on the light switch, and send 'ON' command within 2-3 seconds. If successful, you will see the light flash on and off a couple of times.

    The repeater-node simply relay any command it receives from the controller (I use openhab) to the light wirelessly. There is no physical wire connection between the node and milight.



  • Ok, I meant to say that I had not got any bridge for the mi-light yet. In the first post it is mentioned that you need to pair using a bridge.



  • @Cliff-Karlsson
    thanks, the original post was updated to clarify this.



  • Thanks, next stupid question. How do I control the rgb/dimming features of the lamp? I got a ordinary on/off lamp under device in domoticz.



  • @Cliff-Karlsson
    You have to program your controller to produce the command string and send it to the node. The command string is transmitted as a ASCII string to the 'custom' node. See https://hackaday.io/project/5888-reverse-engineering-the-milight-on-air-protocol for the command format. Sorry I don't use domoticz.



  • Do I need to unpair the bulbs if I want to try pairing again? It got paired as a regular on/of bulb the first time. But I think I found out that I could add mi-lights using a dummy switch. But The bulb are not pairing.



  • @Cliff-Karlsson
    I don't know. Let us know what you find out. 🙂
    To unpair, you turn on the power to the bulb and send 'off' command within seconds.



  • Ok, I tried with several bulbs now. First time I managed to pair as on/off switch but after that I had no luck. If anyone is using this with domoticz please describe the procedure of how to add the bulbs.



  • @ted

    I forgot to ask, but what controller have you been trying them out on? And are there any limitation to how many bulbs one repeater-node can control? I recall reading something about one original controller only being able to control 4 bulbs or similar.



  • Ok, I think I found a clue :), S_CUSTOM seams not to be supported by domoticz so I changed it to "gw.present(0, S_RGBW_LIGHT);"
    So now everything looks ok with a RGB selector and everything. But I still can only turn on and off the bulb and am not able to dim or set colors. So I guess there is some more serious witchcraft going on thats over my head.



  • @Cliff-Karlsson

    The milight uses a speical command, it is not likely to be compatible with the standard RGB light module in domoticz. The information about the milight protocol can be found here: https://hackaday.io/project/5888-reverse-engineering-the-milight-on-air-protocol

    I used openhab to assemble the command string for S_CUSTOM. Using the S_CUSTOM, you can control as many bulb as you want (by using different remote ID field in the milight protocol), although I only have 1 bulb. The node receives the milight protocol in plain ASCII string and convert the string to HEX before sending it out to the bulb. Hope this helps.



  • Ok, thanks for the help but it seams that I will have to use the standard-wifi bridges for now until someone smarter than me fixes the domoticz support.



  • Thank You for this solutin. Everythin works great but...

    I was able to pair with one bulb but I I do not know what to do to pair with others?

    Any idea?

    Best regard



  • @Łukasz-Kostrzewa
    Each bulb is associated with a particular 'remote ID'. Bulbs having the same remote ID will repond to all commands having the same remote ID. Therefore, you can simply pick a different(or the same) remote ID to pair with a second bulb, and the second bulb can be controlled separately(or simultaneously) with the first one. I have not tried it but that should work according to the mi-bulb protocol.



  • Thax for reply

    But I don't understand 😞
    I don't have Milight bridge and I paired one Milight bulb to Dummy switch I have in my Domoticz My sensors.
    And this works great but there is only one dummy switch.
    When I add to arduino code one more (gw.present(0, S_LIGHT);) in Domoticz there is another Dummy switch but it controls the same lights then the first one. I don't know how to add (I don;t know it is possible) a second dummy to control another bulb without milight bridge.



  • Hi Ted

    I understand now:)
    I changed remote id to diffrent values but now my first dummy switch paired to my first bulb doesn't work.
    I need to have another arduino to control another bulb?
    Best regards



  • Another question...
    Is there possibility to add to this code another one to control DHT11 temp and humidity sensor (from my sensors library)
    I wanted to have 2 thing in one:)
    Best regards



  • @Łukasz-Kostrzewa
    The way I'd suggest is to modify the program to add more switches, each switch uses a different remote ID. Alternatively, you can use your controller to generate the necessary command string (with custom ID specific to the bulbs you want to control) and send it to the custom node as an ASCII string. The custom node will relay whatever command it receives to the bulbs.



  • Thx for answer

    I am noob in programming. Maybe You can post an example how to modify the code?

    Best regards



  • Excellent project! I have implemented reversed engineering for (1) some switches (2) LightWaveRF sockets. I tried to implemented Mi-Light with Mysensors but I having spent some time I decided to just buy a WiFi hub ($7) as it is natively supported in Domoticz.

    Mi-Light is an excellent product price wise compare to Philips Hue



  • Hi

    Anyone have idea how to modify the code to pair domoticz to more than one bulb?
    With actual code I am able to ON/OFF only one bulb 😞

    Any idea?

    Best regards



  • Anybody?



  • I would also like this to work with domoticz but as I lack the skills nececary I am now waiting on the next RFlink firmware witch is adding the feature of controlling mi-lights.
    I still think that the node/repeater as descripbed in this topic would be better but as I have no options the RFlink is better than using the standard milight bridge an any way.

    I have added a NRF24L01 PA to my RFlink gateway and am hoping that the range will cover my whole house.



  • Thx for info
    Best regards



  • I have new problem.
    I paired wrong bulb and now I can't unpair it.
    How to do that?
    Best regards



  • Hi Ted,

    Your project looks really amazing and I think it is exactly what I was looking for.
    I want to change my lighting at home. I am thinking of adding 8 LED strips that will be controlled by 2 x 4 Mi-Light remote controls and 2 x wifi bridges. As I would like to still be able to use the wall switches to turn them on/off I was thinking of using your solution. Do you think it will be feasible with your project? Also is there a way to reduce the wifi bridges to 1 instead of having 2?

    Thank you for this great project!

    Iraklis



  • @Łukasz-Kostrzewa
    sorry for the delay. you need to send the unpair command right after turning on the light. see https://hackaday.io/project/5888-reverse-engineering-the-milight-on-air-protocol



  • @Iraklis-Kourtis
    The controller is all you need to control the lights. It does not need wifi bridge



  • Has this been converted to 2.0?

    Also, to build the controller for this i don't need anything special other than the arduino + nrf24l01 correct? I am VERY interested in this



  • i got 2 of my milight bulbs in today. Just wondering if anyone is still using this?



  • @Jason-Brunk said:

    n today. Just wondering if anyone is still using this?

    I would like to use this solution as it seams to be really great to have both a NRF/Mi-light-Repeater for every "node". But my skils are not enough to make this work with RGB-strips/bulbs and to have it working with domoticz. I am using the standard Domoticz way of controllign them using the original mi-light gateways and have also experimented with RF-link mi-light control.

    But my dream-scenario is that some nice coding-wiz will post a complete solution that even newbies can integrate this in this forum-thread. But I would not count on it.



  • I have done a little bit of tinkering with it today. i have not cleaned up the code yet, but I have been able to get my arduino repeater to pair with one of the lights, and turn it on and off. My progress so far.

    • Convert to using the mysensor 2.0 framework
    • setup a bulb and paired
    • can turn bulb on and off

    My next step is to see if i can change colors on the bulb. The only thing I noticed is there is a small delay when switching the radio between the mysensors rf and the milight rf protocol. I may later see if it's possible to do 2 radios. But for now progress is being made with a repeater node.

    Once it's working, Ill see if i can post some samples of how I controlled it via mqtt. (I use openhab)

    If the original author of this sketch is interested I will provide him current code progress. Or I can throw it on github if anyone is interested in tinkering with it. I definitely want to get some documentation together for how to get multiple bulbs working on it.



  • I have put my mods on github.

    https://github.com/brunkj/MySensorsMiLight/

    I have not been able to mess with it since the weekend. Still trying to get some info on the RGB part. If anyone wants to take a shot at it let me know if you make any progress 🙂



  • spent some more time working on this. Still not having luck figuring out a what to send to the V_VAR1 to get the bulb to do anything

    I can send simple on off for S_LIGHT V_STATUS

    if (message.type == V_STATUS)
      {
        //Serial.println("triggered V_STATUS");
        mlr.begin();
    
        // Change light status
        Serial.println(message.getBool());
        if ( message.getBool())
        {
          Serial.println("here");
          // Serial.println("triggered ON");
          sendCommand (outgoingPacket_on, sizeof(outgoingPacket_on));
        }
    
    
        else {
          //  Serial.println("triggered off");
          sendCommand(outgoingPacket_off, sizeof(outgoingPacket_off));
        }
        _begin();
      }
    

    Easy. But the V_VAR1 on S_CUSTOM I can't figure out what to put in the payload

    if (message.type == V_VAR1)
      {
        // Serial.println("triggered V_VAR1");
        
        incomingCommand = (char *)message.getCustom();
        Serial.println((char *)message.getCustom());
         mlr.begin();
         Serial.println("#############");
        for (int i=0; i<sizeof(outgoingPacket); i++)
        { outgoingPacket[i] = 16*char_to_uint8_t(incomingCommand[i*2]) + char_to_uint8_t(incomingCommand[i*2+1]);
          Serial.println(outgoingPacket[i]);
          }
        Serial.println("#############");
        Serial.write(outgoingPacket, 7);
        sendCommand(outgoingPacket, sizeof(outgoingPacket));
        _begin();
      }
    
    

    I have referenced the hacking milight protocol pages and many other, I just can't seem to get it right to get my bulb to do anything.

    Anyone want to take a shot at it? or have payload data I could try?

    full sketch

    #define MY_DEBUG 
    #define MY_RADIO_NRF24
    #define MY_REPEATER_FEATURE
    #include <MyConfig.h>
    #include <MySensors.h>
    
    #include <SPI.h>
    #define CE_PIN 9     //CE and CSN pin for nrf24 radio
    #define CSN_PIN 10
    #include <nRF_24L01.h>
    #include <avr/power.h>
    #include <printf.h>
    
    #include "PL1167_nRF24.h"
    #include "MiLightRadio.h"
    
    
    #define NODE_ID 100
    #define mi_command_repeat 30   //# of times to resend the command to bulb
    
    
    
    
    RF_24 mi_radio(CE_PIN, CSN_PIN);
    PL1167_nRF24 prf(mi_radio);
    MiLightRadio mlr(prf);
                                           // B0-176   F2-242    EA-234    6D    B0    02    f0
    static uint8_t outgoingPacket_on[7] = { 0xB0, 0xF2, 0xEA, 0x6D, 0x91, 0x03, 0x00};  //the first three #s are remote ID, replace with yours
    static uint8_t outgoingPacket_off[7] = { 0xB0, 0xF2, 0xEA, 0x04, 0x91, 0x04, 0x00};
    uint8_t outgoingPacket[7];
    
    #define sizeofincomingCommand 15 //command comes in text form of 7 uint8_t, with an additional NULL at end
    
    char *incomingCommand;    //array for incoming command
    
     
    boolean mi_radio_state = false;
    void presentation()  
    {  
      //Send the sensor node sketch version information to the gateway
      sendSketchInfo("Milight controller", "1.0");
    }
    
    void setup()
    {  
      
       //clock_prescale_set(clock_div_2);     //for a barebone atmega328p, this  will make the CPU running at 4MHz.
      //Serial.begin(115200);
      // The third argument enables repeater mode.
    
      //Send the sensor node sketch version information to the gateway
      present(0, S_LIGHT);
      present(1, S_CUSTOM);
    
    
    
    }
    
    
    
    
    void receive(const MyMessage &message) {
      // The command will be transmitted in V_VAR1 type, in the following 7 byte format: ID1 ID2 ID3 COLOR BRIGHTNESS COMMAND.
      // see https://hackaday.io/project/5888-reverse-engineering-the-milight-on-air-protocol
      Serial.println(message.type);
      if (message.type == V_STATUS)
      {
        //Serial.println("triggered V_STATUS");
        mlr.begin();
    
        // Change light status
        Serial.println(message.getBool());
        if ( message.getBool())
        {
          Serial.println("here");
          // Serial.println("triggered ON");
          sendCommand (outgoingPacket_on, sizeof(outgoingPacket_on));
        }
    
    
        else {
          //  Serial.println("triggered off");
          sendCommand(outgoingPacket_off, sizeof(outgoingPacket_off));
        }
        _begin();
      }
    
    
      if (message.type == V_VAR1)
      {
        // Serial.println("triggered V_VAR1");
        
        incomingCommand = (char *)message.getCustom();
        Serial.println((char *)message.getCustom());
         mlr.begin();
         Serial.println("#############");
        for (int i=0; i<sizeof(outgoingPacket); i++)
        { outgoingPacket[i] = 16*char_to_uint8_t(incomingCommand[i*2]) + char_to_uint8_t(incomingCommand[i*2+1]);
          Serial.println(outgoingPacket[i]);
          }
        Serial.println("#############");
        Serial.write(outgoingPacket, 7);
        sendCommand(outgoingPacket, sizeof(outgoingPacket));
        _begin();
      }
    
    //gw.begin(incomingMessage, NODE_ID, true);
    
    
    
    
    }
    
    void sendCommand(uint8_t mi_Command[7], int sizeofcommand)
    { for (int i = 0; i < mi_command_repeat; i++)
      { mlr.write(mi_Command, sizeofcommand);
      }
    }
    
    uint8_t char_to_uint8_t(char c) 
    {
    	uint8_t i;
    	if (c <= '9')
    		i = c - '0';
    	else if (c >= 'a')
    		i = c - 'a' + 10;
    	else
    		i = c - 'A' + 10;
    	return i;
    }
    


  • @Jason-Brunk
    unfortunately i havnt got my own milight bulbs but for what i've seen on the
    reverse engineered protocol page the payload must be something like
    "07B0F2EA359001B9ACF9" for all on or
    "07B0F2EA7D910FD4EC72" for green

    or the part "07B0F2EA" must be the ID so the payload
    is somethink like "359001B9ACF9" for all on and
    "7D910FD4EC72" for green



  • @ted are you there and can get a hint please? 🙂



  • @n1ck1355 @Jason-Brunk
    sorry i'm been really busy with job recently. I used openhab to send the payload to V_VAR1 and S_CUSTOM. When I get home tonight, I'll post the openhab rule file so people can get some sense how to control color.



  • that's really great 🙂 Thanks!



  • @n1ck1355
    sorry for the delay. Here is what I learned from https://hackaday.io/project/5888-reverse-engineering-the-milight-on-air-protocol

    Basically, the mi controller will receive text string and convert them into HEX format and send it to the bulb. The text string should be formatted as the following (+ added for easy of reading, no '+' in the actual command):

    ID + color + brightness + button code + seq

    The ID is the ID of the bulb to be controlled, it is six byte in ASCII but will be converted into 3 byte HEX before sending to the bulb.
    color, brightness and button code are each 2 byte in ASCII and will be converted into 1 byte HEX and send to bulb.
    Seq is 2 byte in ASCII but it appears that you can just use "00".

    To change color, you need to send a color code (e.g.: "00"=purple, "1B"=red, "40"=yellow,e tc) and using button code "OF".
    To change back to white, you use "04" as color code and "13" as button code.

    The detailed button code definition can be found here:
    https://cdn.hackaday.io/images/1224221432724803073.jpg

    Hope this helps.



  • Thank you @ted 🙂
    i already played with it and can turn the bulbs on/off. i will play around with your
    information to make the other funktions work.

    But what i see is that you cannot e.g. dim the bulbs softly from say 100% to 20% cause
    that would be more commands behind each other. But the node must reset itself after
    each command by calling _Begin() and that takes some time..
    any suggestions to resolve that?



  • @n1ck1355
    my only solution is to use two radios, one receives command from the gateway and the other sending command to the bulbs. it might be doable with just 1 arduino by using softSPI.


  • Hardware Contributor

    @ted said:

    @n1ck1355
    my only solution is to use two radios, one receives command from the gateway and the other sending command to the bulbs. it might be doable with just 1 arduino by using softSPI.

    I don't see why you would need SoftSPI for that ? It should just need some change for CE and CSN pins for the NRF that is used to send data to the milights. I will try to find time to check that this week.



  • @Nca78 :

    did you have success with thw NRF boards connecting?


  • Hardware Contributor

    @n1ck1355 said:

    @Nca78 :

    did you have success with thw NRF boards connecting?

    Hello, unfortunately I had no time to test it, I was busy with my Livolo switch 😛



  • I just tried out openhab2, would it be easier controling the bulbs from openhab2 or do I still to do alot of "coding" on my own?


  • Hardware Contributor

    Hello, few months have passed and I finally had a look at the code from @Jason-Brunk
    I made a MiLightBulb class with methods to set on/off, set brightness level, set color and set animation. It still needs improvements as brightness is not working, some colors are a bit off and I didn't test animation yet but it's starting to take shape and I can use it from RGB light control in domoticz.

    I have connected 2 nrf24 also, using pins 7&8 for the one sending MiLight messages instead of 9&10 and it running fine as expected, no use to call begin() all the time: much more reactive.
    I'll publish the code as soon as I have time to finish and clean up.



  • Great news @Nca78



  • any updates? I have a couple milight bulbs ready to test 🙂


  • Hardware Contributor

    @Jason-Brunk sorry I received my PCBs for Livolo switches so these will have my priority at the moment. And we're still in the lunar new year holidays here, not much time available.



  • Totally understand. That's another project I am interested in 🙂



  • Hi

    I have read through this thread fully and the concept look great. I am confused as to the hardware that is required thought. I have a mysensors gateway connetcted to wifi and some sensors setup and working on Home Assistant. What do I need to build to implement this solution, and what would I have to install in HA.

    Thanks for any help
    Laurie



  • Hello,

    is this thread still alive ?
    I am on a Raspberry Pi 3 an i have connected an nrf radio.

    PiGateway or PiGatewaySerial are both working and also openmilight_pi is compiled and ready.

    My Problem is:
    In the first post its said to send multiple On commands to the milight to pair it.
    This shall work even without the original remote controller.

    But how ?

    How to use the Gateway or openmilight to send a general on command ?
    I cannot see it from the hackaday page. Everywhere the ID is needed. Which i dont have when using only Pi, nRF and a milight rgb box to controll a strip.

    Please can someone light me up ???



  • @Dlay I think there has been little activity on this thread. I had some issues too and I ended up buying Wifi module to control LED strip. It is natively supported by Domoticz so it works fine for me.


  • Hardware Contributor

    Hello, I'm testing my MiLight shield for NModule, and so far it's working well, so I'll post some code soon.
    Even without the NModule and MiLight controller shield it will be possible to use the same wiring to build one.


 

336
Online

8.0k
Users

8.8k
Topics

94.4k
Posts