{"id":4420,"date":"2023-09-28T12:00:08","date_gmt":"2023-09-28T19:00:08","guid":{"rendered":"https:\/\/www.cloudacm.com\/?p=4420"},"modified":"2023-10-02T04:16:47","modified_gmt":"2023-10-02T11:16:47","slug":"kauf-rgbww-smart-bulb-esp8266-firmware","status":"publish","type":"post","link":"https:\/\/www.cloudacm.com\/?p=4420","title":{"rendered":"Kauf RGBWW Smart Bulb ESP8266 Firmware"},"content":{"rendered":"<p>This post will provide some experiences with the Kauf RGBWW Smart Bulb and firmware developed with the Arduino IDE.\u00a0 Details about these bulbs can be found on GitHub, <a href=\"https:\/\/github.com\/KaufHA\/kauf-rgbww-bulbs\">https:\/\/github.com\/KaufHA\/kauf-rgbww-bulbs<\/a> or from the manufacturer&#8217;s website, <a href=\"https:\/\/kaufha.com\/\">https:\/\/kaufha.com\/<\/a><\/p>\n<p>I referenced this post about the bulb, <a href=\"https:\/\/digiblur.com\/2021\/09\/15\/preflashed-esphome-tasmota-smart-bulbs-with-an-added-bonus-kauf-blf10\/\">https:\/\/digiblur.com\/2021\/09\/15\/preflashed-esphome-tasmota-smart-bulbs-with-an-added-bonus-kauf-blf10\/<\/a>.\u00a0 It mentions that a new firmware can be uploaded through the device web interface.\u00a0 My attempts to upload firmware compiled in the Arduino IDE were not successful. Initially I thought it was an incorrect OTA flash size setting, but each attempt failed.<\/p>\n<p>One thing that I found odd in my attempts to upload my own firmware was the disruption of wireless service to another ESP01 module nearby. This would happen anytime the bulb was powered on within 2 meters of the ESP01 module. I tried this with another ESP8266 device located in another area and noticed the same issue. The ESP32 modules did not have this problem. This unexpected behavior happened with either of the Kauf BLF10 or BR30 bulbs I had on hand at the time. I&#8217;ll come back to this later.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Kauf_RGBWW_SmartBulb_SolderPads.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4465\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Kauf_RGBWW_SmartBulb_SolderPads.png\" alt=\"\" width=\"248\" height=\"440\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Kauf_RGBWW_SmartBulb_SolderPads.png 248w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Kauf_RGBWW_SmartBulb_SolderPads-169x300.png 169w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Kauf_RGBWW_SmartBulb_SolderPads-152x270.png 152w\" sizes=\"auto, (max-width: 248px) 100vw, 248px\" \/><\/a><\/p>\n<p>I decided to remove the bulb cover and solder leads on the programming pads to upload my firmware. There are 5 pads that will need to have either a jig or soldered jumpers connected to them.\u00a0 They are GND, RX, TX, 3V3, and IO0.\u00a0 The RX and TX pins are UART receive and transmit pads respectively.<\/p>\n<p><iframe loading=\"lazy\" title=\"Kauf_RGBWW_SmartBulb_ProgramPads\" src=\"https:\/\/player.vimeo.com\/video\/867172534?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" width=\"270\" height=\"480\" frameborder=\"0\"><\/iframe><\/p>\n<p>The power supply should be a 3.3 volt source which attaches to pad 3V3 and ground to the GND pad.\u00a0 To get the ESP module in programming mode, the GPIO pin IO0 pad should be held to ground when powering on the bulb through the 3.3 volt source.\u00a0 DO NOT use any AC power source when flashing the ESP module, you risk damaging property or injuring someone.\u00a0 Below is an example of the firmware flashing connections.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/ESP8266_FTDI-3.3V_Flashing.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4477\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/ESP8266_FTDI-3.3V_Flashing.png\" alt=\"\" width=\"663\" height=\"374\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/ESP8266_FTDI-3.3V_Flashing.png 663w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/ESP8266_FTDI-3.3V_Flashing-300x169.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/ESP8266_FTDI-3.3V_Flashing-479x270.png 479w\" sizes=\"auto, (max-width: 663px) 100vw, 663px\" \/><\/a><\/p>\n<p>This link provides some guidance on flashing the ESP8266 module, <a href=\"https:\/\/www.thissmarthouse.net\/howto-flash-firmware-sonoff-t1-switch\/\">https:\/\/www.thissmarthouse.net\/howto-flash-firmware-sonoff-t1-switch\/<\/a>. Flashing the ESP module worked fine and the new firmware has functions for me to do OTA updates. After my firmware was loaded, the disruption anomaly was no longer happening, so I suspect the source of the problem isn&#8217;t with the hardware.<\/p>\n<p>The Kauf LED bulbs included a manual that clearly shows what color LED GPIO pin it uses. The manual is also available online from the GitHub site.\u00a0 This was extremely helpful information to have and saved me time from having to dig for it. The typical rainbow color wheel used to control RGB LED lights follows a 3 phase progression. This link provides details and history of the color wheel, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Color_wheel\">https:\/\/en.wikipedia.org\/wiki\/Color_wheel<\/a>.\u00a0 Below is a rainbow color band to show how each LED color blends.\u00a0 As the color is changed through the band, the RGB values follow a 3 phase wave pattern.\u00a0 Only one color is at its peak value while either of the two colors change.<\/p>\n<p><iframe loading=\"lazy\" title=\"RGB_Rainbow\" src=\"https:\/\/player.vimeo.com\/video\/867048702?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" width=\"660\" height=\"110\" frameborder=\"0\"><\/iframe><\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Rainbow_Color_Curve.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4503 size-full\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Rainbow_Color_Curve.png\" alt=\"\" width=\"605\" height=\"340\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Rainbow_Color_Curve.png 605w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Rainbow_Color_Curve-300x169.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Rainbow_Color_Curve-480x270.png 480w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/a><\/p>\n<p>The rainbow color wheel however isn&#8217;t a typical use case of LED lighting, color temperature is. The color temperature range can be best compared with a sunrise or sunset, deep reds and oranges fading into dimly lit white and on to deeper blues. The scale is used as a temperature scale of stars measured in kelvins. More about color temperature can be found here, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Color_temperature\">https:\/\/en.wikipedia.org\/wiki\/Color_temperature<\/a>.\u00a0 Below is an example of a color temperature band.\u00a0 The colors change in a linear progression.<\/p>\n<p><iframe loading=\"lazy\" title=\"RGB_Temperature\" src=\"https:\/\/player.vimeo.com\/video\/867050760?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" width=\"660\" height=\"110\" frameborder=\"0\"><\/iframe><\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Color_Temp_Curve.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4504\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Color_Temp_Curve.png\" alt=\"\" width=\"605\" height=\"340\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Color_Temp_Curve.png 605w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Color_Temp_Curve-300x169.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Color_Temp_Curve-480x270.png 480w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/a><\/p>\n<p>There are other color scales that could be used, here are examples from Plotly, <a href=\"https:\/\/plotly.com\/javascript\/colorscales\">https:\/\/plotly.com\/javascript\/colorscales<\/a>. There are interesting color sweeps available such as inferno, viridis, or tealrose. Based on the setting they are placed, these color scales could provide a better suited palette that&#8217;s more sophisticated than the traditional rainbow or color temperature scales.\u00a0 Some of these scales are purposely set to help those with color blindness, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Color_blindness\">https:\/\/en.wikipedia.org\/wiki\/Color_blindness<\/a>.\u00a0 Below is an example of a viridis color band.\u00a0 Here the colors change in a curved progression.<\/p>\n<p><iframe loading=\"lazy\" title=\"RGB_Viridis\" src=\"https:\/\/player.vimeo.com\/video\/867051288?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" width=\"660\" height=\"110\" frameborder=\"0\"><\/iframe><\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Viridis-Color_Curve.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4508\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Viridis-Color_Curve.png\" alt=\"\" width=\"605\" height=\"340\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Viridis-Color_Curve.png 605w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Viridis-Color_Curve-300x169.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Viridis-Color_Curve-480x270.png 480w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/a><\/p>\n<p>Using a RGB LED for inspections isn&#8217;t something new and this link provides some guidelines for visual systems, <a href=\"https:\/\/www.edn.com\/choose-the-right-lighting-for-inspection\/\">https:\/\/www.edn.com\/choose-the-right-lighting-for-inspection\/<\/a>. The versitily of the RGB light source for the purpose of object inspection is appealing because it&#8217;s adapt to a variety of use cases. However this is likely not the intended use of these bulbs so the reliability should be tested.<\/p>\n<figure style=\"width: 411px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"\" src=\"https:\/\/sci.esa.int\/sci-images\/8b\/HIFI-blacklight-inspection.JPG\" alt=\"\" width=\"411\" height=\"308\" \/><figcaption class=\"wp-caption-text\">The focal plane unit of HIFI is inspected for dust, using ultraviolet light. Source ESA https:\/\/sci.esa.int\/web\/herschel\/-\/41355-inspection-of-hifi-with-uv-light<\/figcaption><\/figure>\n<p>The color spectrum of the Kauf LED bulb offers a wide range because it has five different LED color sources. These are Red, Green, Blue, Warm White, and Cool White. Here&#8217;s a site describing the difference between cool and warm lighting, <a href=\"https:\/\/www.homeadvisor.com\/r\/warm-light-vs-cool-light\/\">https:\/\/www.homeadvisor.com\/r\/warm-light-vs-cool-light\/<\/a>. It&#8217;s ironic that the widely accepted description of warm to cool is the opposite of what their actual color temperature range is, since a temperature of 1900 Kelvin is cooler than 10000 Kelvin. This site provides some comparisons of color spectrum from legacy lighting using spectroscopy, <a href=\"https:\/\/smallpond.ca\/jim\/misc\/cfl\/\">https:\/\/smallpond.ca\/jim\/misc\/cfl\/<\/a><\/p>\n<figure style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"\" src=\"https:\/\/smallpond.ca\/jim\/misc\/cfl\/spectra.jpg\" alt=\"\" width=\"600\" height=\"217\" \/><figcaption class=\"wp-caption-text\">Emission spectra of some compact fluorescent lamps (CFL bulbs) &#8211; Source Jim Elder https:\/\/smallpond.ca\/jim\/misc\/cfl\/<\/figcaption><\/figure>\n<p>As mentioned earlier, the first batch of out of the box Kauf LED bulbs had a strange effect.\u00a0 When these bulbs were powered on, the neighboring ESP8266 modules would loose their wifi network connection.\u00a0 Powering off the bulbs cleared the issue and the wifi network connections were restored on the ESP8266 modules.\u00a0 Be mindful that these bulbs were fresh out of the box with no configuration on my part.\u00a0 I wanted to investigate this further but had already flashed my firmware on the bulbs, so I ordered additional bulbs in hopes of capturing the RF pattern using my NRF24L01 modules.\u00a0 When the new bulbs arrived, they did not exhibit this effect on neighboring modules.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/NRF24L01_Readings.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-4500\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/NRF24L01_Readings-300x197.png\" alt=\"\" width=\"300\" height=\"197\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/NRF24L01_Readings-300x197.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/NRF24L01_Readings-411x270.png 411w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/NRF24L01_Readings.png 640w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Since the new bulbs had no RF anomaly, I did notice a pattern out of the box with how the LEDs were lit.\u00a0 When powered on for the first time, the blub would flash on then turn red for a bit, then back on.\u00a0 If I turned the bulb off and back on, it would just turn on.\u00a0 Then it was followed by 3 green lights with each successive power cycle.\u00a0 As I power cycled the bulb I began to see a repeatable pattern.\u00a0 Here is a spectrogram of what the bulb colors were.\u00a0 The video contains a window of the spectrogram slit inside a larger window of the same slit stretched to the width of the video.<\/p>\n<p><iframe loading=\"lazy\" title=\"Kauf_RGBWW_SmartBulb_Factory-State\" src=\"https:\/\/player.vimeo.com\/video\/867171359?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" width=\"720\" height=\"406\" frameborder=\"0\"><\/iframe><\/p>\n<p>It was difficult to capture the bulb color directly with a camera due in part to color correction or washout, so this was the reason for using the spectrogram.\u00a0 I&#8217;m unsure if the first batch of bulbs behaved this way.\u00a0 I&#8217;ll follow up with more spectrograms and RF scans should a different batch arrive with the original wifi disruption issue.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_3840.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4487\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_3840.png\" alt=\"\" width=\"338\" height=\"600\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_3840.png 338w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_3840-169x300.png 169w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_3840-152x270.png 152w\" sizes=\"auto, (max-width: 338px) 100vw, 338px\" \/><\/a><\/p>\n<p>The flash memory on the bulb is a Puya Semiconductor P25D80H with 1MB of storage.\u00a0 I found the datasheet online here, <a href=\"https:\/\/datasheet.lcsc.com\/lcsc\/2006121819_-PUYA--P25D80H-TSH-IT_C559201.pdf\">https:\/\/datasheet.lcsc.com\/lcsc\/2006121819_-PUYA&#8211;P25D80H-TSH-IT_C559201.pdf<\/a>.\u00a0 The write cycles in the datasheet were 100,000.\u00a0 This translates to just under 3 years of service if the flash memory performed writes every 15 minutes.\u00a0 It&#8217;s probably not the best data logger for anything with a faster refresh rate.<\/p>\n<p>Here is the firmware code used to flash the bulb in the Arduino IDE.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">\/**\r\n\r\n  Header\r\n\r\n  Title: ESP8266 HTTP Client Firmware Update with MQTT controlled RGBWW and Saved Settings using Flash Memory\r\n  Version: 1\r\n  Filename: ESP8266-Kauf-RGBWW-Blub_HTTP-Client-Firmware-Update_MQTT_RGBWW-LED_ver1.ino\r\n\r\n  Date: 7\/27\/2023\r\n  \r\n\r\n*\/\r\n\r\n\r\n\r\n\r\n\/\/ Libraries and Declarations\r\n\r\n#include &lt;Arduino.h&gt;\r\n\r\n#include &lt;ESP8266WiFi.h&gt;\r\n\r\n#include &lt;PubSubClient.h&gt;\r\nWiFiClient espClient;\r\nPubSubClient MQTTclient(espClient);\r\nlong laststats = 0;\r\nint programflag = 0;\r\nint flashwrite = 0;\r\n\r\n#include &lt;ESP8266HTTPClient.h&gt;\r\n#include &lt;ESP8266httpUpdate.h&gt;\r\n\r\n\r\n\/\/ NTP Libraries, Declarations, and Variables\r\n#include &lt;NTPClient.h&gt;\r\n#include &lt;WiFiUdp.h&gt;\r\nWiFiUDP ntpUDP;\r\nNTPClient timeClient(ntpUDP, \"pool.ntp.org\");\r\n\/\/Week Days\r\nString weekDays[7]={\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"};\r\n\/\/Month names\r\nString months[12]={\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"};\r\n\r\n\r\n\/\/ include library to read and write from flash memory\r\n#include &lt;EEPROM.h&gt;\r\n\r\n\/\/ define the number of bytes you want to access\r\n#define EEPROM_SIZE 1\r\n\r\n\/\/ Variables\r\n\r\n\/\/ MQTT Broker\r\nconst char* mqtt_server = \"mqtt-broker-ip-address\";     \/\/ Put your MQTT Broker here\r\n\r\n\/\/ Your WiFi credentials\r\nconst char* ssid =     \"wifi-ssid\";               \/\/ Put your SSID here\r\nconst char* password = \"wifi-psk\";                \/\/ Put your PASSWORD here\r\n\r\n\/\/Your Domain name with URL path or IP address with path\r\nconst char* firmware_server = \"http:\/\/node-red-ip-address:1880\/get-firmware-path\";\r\n\r\n\/\/ Global variables\r\nint totalLength;       \/\/total size of firmware\r\nint currentLength = 0; \/\/current size of written firmware\r\n\r\nunsigned long lasttimeupdate = 0; \/\/ Time counter for periodic NTP time checks\r\nunsigned long lasttimereboot = 0; \/\/ Time counter for periodic reboots to avoid millis rollover\r\n\r\nString FirmwarePath;\r\n\r\nADC_MODE(ADC_VCC);  \/\/ See comment block below for more details\r\n\/*\r\n  see - http:\/\/arduino.esp8266.com\/Arduino\/versions\/2.0.0-rc2\/doc\/libraries.html\r\n\r\n  ESP.getVcc() may be used to measure supply voltage. ESP needs to reconfigure the ADC at \r\n  startup in order for this feature to be available. Add the following line to the top of \r\n  your sketch to use getVcc:\r\n\r\n  ADC_MODE(ADC_VCC);\r\n\r\n  TOUT pin has to be disconnected in this mode.\r\n\r\n  Note that by default ADC is configured to read from TOUT pin using analogRead(A0), and \r\n  ESP.getVCC() is not available.\r\n\r\n *\/\r\n \r\n\r\nint RedLED = 4;          \/\/ Red LED connected to digital pin 4\r\nint GreenLED = 12;       \/\/ Green LED connected to digital pin 12\r\nint BlueLED = 14;        \/\/ Blue LED connected to digital pin 14\r\nint ColdWhiteLED = 5;    \/\/ Cold White LED connected to digital pin 5\r\nint WarmWhiteLED = 13;   \/\/ Warm White LED connected to digital pin 13\r\n\r\n\r\n\r\n\r\n\/\/ MQTT Functions\r\n\r\nvoid callback(char* topic, byte* message, unsigned int length) {\r\n  \r\n  String messageTemp;\r\n  \r\n  for (int i = 0; i &lt; length; i++) {\r\n    messageTemp += (char)message[i];\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/CommitFlash\") {\r\n    if(messageTemp == \"WriteFlash\"){\r\n      EEPROM.write(0, flashwrite);\r\n      EEPROM.commit();\r\n    }\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/HTTP-Get\") {\r\n    if(messageTemp == \"CheckFirmware\"){\r\n      FirmwarePath = httpGETRequest(firmware_server);\r\n    }\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/HTTP-Get\") {\r\n    if(messageTemp == \"UpdateFirmware\"){\r\n      FirmwarePath = httpGETRequest(firmware_server);\r\n      t_httpUpdate_return ret = ESPhttpUpdate.update(espClient, FirmwarePath);\r\n    }\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/UpdateTime\") {\r\n    if(messageTemp == \"CheckTime\"){\r\n          timeClient.update();\r\n    }\r\n  }  \r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/Reboot\") {\r\n    if(messageTemp == \"Reboot\"){\r\n      ESP.restart();\r\n    }\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/RedLED\") {\r\n   int intTemp = messageTemp.toInt();\r\n   analogWrite(RedLED, intTemp);\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/GreenLED\") {\r\n   int intTemp = messageTemp.toInt();\r\n   analogWrite(GreenLED, intTemp);\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/BlueLED\") {\r\n   int intTemp = messageTemp.toInt();\r\n   analogWrite(BlueLED, intTemp);\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/ColdWhiteLED\") {\r\n   int intTemp = messageTemp.toInt();\r\n   analogWrite(ColdWhiteLED, intTemp);\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/WarmWhiteLED\") {\r\n   int intTemp = messageTemp.toInt();\r\n   flashwrite = intTemp;\r\n   analogWrite(WarmWhiteLED, intTemp);\r\n  }\r\n\r\n  if (String(topic) == \"ESP8266-Kauf-RGBWW-Blub\/ColorTemp\") {\r\n   int intTemp = messageTemp.toInt();\r\n   if ( intTemp &lt;= 64 ) {\r\n      analogWrite(RedLED, intTemp*4);\r\n      analogWrite(GreenLED, 0);\r\n      analogWrite(BlueLED, 0);\r\n   }\r\n   if ( intTemp &gt; 64 &amp;&amp; intTemp &lt; 129 ) {\r\n      analogWrite(RedLED, 255);\r\n      analogWrite(GreenLED, (intTemp-64)*2);\r\n      analogWrite(BlueLED, 0);\r\n   }\r\n   if ( intTemp &gt; 128 &amp;&amp; intTemp &lt; 193 ) {\r\n      analogWrite(RedLED, 255);\r\n      analogWrite(GreenLED, (intTemp-64)*2);\r\n      analogWrite(BlueLED, (intTemp-128)*4);\r\n   }\r\n   if ( intTemp &gt; 192 &amp;&amp; intTemp &lt; 256 ) {\r\n      analogWrite(RedLED, 255-(intTemp-192));\r\n      analogWrite(GreenLED, 255-(intTemp-192));\r\n      analogWrite(BlueLED, 255);\r\n   }\r\n  }\r\n  \r\n}\r\n\r\n\r\n\r\nvoid reconnect() {\r\n  \/\/ Loop until we're reconnected\r\n  while (!MQTTclient.connected()) {\r\n    \/\/ Attempt to connect\r\n    if (MQTTclient.connect(\"ESP8266-Kauf-RGBWW-Blub\")) {\r\n      \/\/ Subscribe\r\n      \/\/ Do you not subscribe to my methods?\r\n      \/\/ ESP8266-Kauf-RGBWW-Blub\/# for everything, or ESP8266-Kauf-RGBWW-Blub\/Uptime for just the Uptime\r\n      MQTTclient.subscribe(\"ESP8266-Kauf-RGBWW-Blub\/#\");\r\n    } else {\r\n      \/\/ Wait 5 seconds before retrying\r\n      delay(5000);\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\/\/ HTTP Get Functions\r\nString httpGETRequest(const char* firmware_server) {\r\n  HTTPClient http;\r\n    \r\n  \/\/ Your Domain name with URL path or IP address with path\r\n  http.begin(espClient, firmware_server);\r\n  \r\n  \/\/ Send HTTP POST request\r\n  int httpResponseCode = http.GET();\r\n  \r\n  String payload = \"{}\"; \r\n  \r\n  if (httpResponseCode&gt;0) {\r\n    payload = http.getString();\r\n  }\r\n  \/\/ Free resources\r\n  http.end();\r\n\r\n  return payload;\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\nvoid UpdateStats() {\r\n  \r\n  long stats = millis();\r\n  if (stats - laststats &gt; 5000) {\r\n    laststats = stats;\r\n\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/Firmware\", \"ESP8266-Kauf-RGBWW-Blub_HTTP-Client-Firmware-Update_MQTT_RGBWW-LED_ver1\");    \r\n    String StringUptime = String(millis());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/Uptime\", StringUptime.c_str());\r\n    String StringHWAddress = String(WiFi.macAddress());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/HWAddress\", StringHWAddress.c_str());   \r\n    String StringWifiSignal = String(WiFi.RSSI());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/WifiSignal\",StringWifiSignal.c_str());  \r\n    \r\n    String StringFreeHeapSize = String(ESP.getFreeHeap());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/FreeHeapSize\",StringFreeHeapSize.c_str());  \r\n    String StringHeapFragmentation = String(ESP.getHeapFragmentation());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/HeapFragmentation\",StringHeapFragmentation.c_str());  \r\n    String StringMaxFreeBlockSize = String(ESP.getMaxFreeBlockSize());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/MaxFreeBlockSize\",StringMaxFreeBlockSize.c_str());  \r\n    String StringSketchSize = String(ESP.getSketchSize());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/SketchSize\",StringSketchSize.c_str());  \r\n    String StringFreeSketchSpace = String(ESP.getFreeSketchSpace());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/FreeSketchSpace\",StringFreeSketchSpace.c_str());  \r\n    String StringCpuFreqMHz = String(ESP.getCpuFreqMHz());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/CpuFreqMHz\",StringCpuFreqMHz.c_str());\r\n    String StringChipId = String(ESP.getChipId());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/ChipId\",StringChipId.c_str());  \r\n    String StringVcc = String(ESP.getVcc());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/Vcc\",StringVcc.c_str());  \r\n\r\n    \/\/Get a Time Structure\r\n    String formattedTime = timeClient.getFormattedTime();\r\n    String StringformattedTime = String(formattedTime);\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/Time\",StringformattedTime.c_str());  \r\n\r\n    \/\/Get a Date Structure\r\n    time_t epochTime = timeClient.getEpochTime();\r\n    struct tm *ptm = gmtime ((time_t *)&amp;epochTime); \r\n    int monthDay = ptm-&gt;tm_mday;\r\n    int currentMonth = ptm-&gt;tm_mon+1;\r\n    String currentMonthName = months[currentMonth-1];\r\n    int currentYear = ptm-&gt;tm_year+1900;\r\n    \r\n    \/\/Publish complete date:\r\n    String StringcurrentDate = String(currentMonth) + \"\/\" + String(monthDay) + \"\/\" + String(currentYear);\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/Date\",StringcurrentDate.c_str());  \r\n    \r\n    \/\/Publish Epoch:\r\n    String StringEpochTime = String(timeClient.getEpochTime());\r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/EpochTime\",StringEpochTime.c_str());  \r\n\r\n    \r\n    \/\/ String StringFirmwarePath = String(FirmwarePath); \r\n    MQTTclient.publish(\"ESP8266-Kauf-RGBWW-Blub\/FirmwarePath\",FirmwarePath.c_str());   \r\n  }\r\n  \r\n}\r\n\r\n\r\n\r\n\r\n\r\n\/\/ Setup Function\r\nvoid setup() {\r\n  \r\n  EEPROM.begin(EEPROM_SIZE);\r\n  int intTemp = EEPROM.read(0);\r\n  analogWrite(WarmWhiteLED, intTemp);\r\n  \r\n  delay(1000);\r\n  \r\n  WiFi.mode(WIFI_STA);\r\n  WiFi.begin(ssid, password);\r\n  while (WiFi.status() != WL_CONNECTED)\r\n    {\r\n      \/\/ Just wait it out\r\n      delay(250);\r\n    }\r\n  \r\n  MQTTclient.setServer(mqtt_server, 1883);\r\n  MQTTclient.setCallback(callback);\r\n\r\n  ESPhttpUpdate.setClientTimeout(2000);  \/\/ default was 8000\r\n\r\n  timeClient.begin(); \/\/ Initialize a NTPClient to get time\r\n  timeClient.setTimeOffset(-25200);\r\n  \/\/ Set offset time in seconds to adjust for your timezone, for example:\r\n  \/\/ GMT -7 = -25200 (see - https:\/\/time.gov\/)\r\n  delay(1000);\r\n  timeClient.update();\r\n  \r\n}\r\n\r\n\r\n\/\/ Main Loop Function\r\nvoid loop() {\r\n  \r\n  if (!MQTTclient.connected()) {\r\n    reconnect();\r\n  } \r\n  MQTTclient.loop();\r\n  UpdateStats();\r\n\r\n  \/\/ Update time from NTP source every 1 day (24 * 60 * 60 * 1000 = 86400000 milli-seconds)\r\n  unsigned long timeupdate = millis();\r\n  if (timeupdate - lasttimeupdate &gt; 86400000) {\r\n    lasttimeupdate = timeupdate;\r\n    timeClient.update(); \r\n  }\r\n\r\n  \/\/ Reboot microcontroller every 30 day to avoid millis() rollover (30 * 24 * 60 * 60 * 1000 = 2592000000 milli-seconds)\r\n  unsigned long timereboot = millis();\r\n  if (timereboot - lasttimereboot &gt; 2592000000) {\r\n      \/\/ Reboot command\r\n      ESP.restart();\r\n  }\r\n\r\n\r\n}\r\n\r\n\r\n\/**\r\n\r\n  Footer\r\n  \r\n*\/<\/pre>\n<p>Here are the key features of this firmware build.<\/p>\n<ul>\n<li>WiFi client to existing network<\/li>\n<li>MQTT client for publishing and subscribing from a broker<\/li>\n<li>NTP client timestamp for local time zone<\/li>\n<li>RGBWW values can be stored to flash and are referenced on reboot<\/li>\n<li>Firmware updates can be initiated through Node-Red<\/li>\n<li>Color temperature scale for RGB LEDs<\/li>\n<li>Scheduled reboot to avoid rollover of millis() function<\/li>\n<\/ul>\n<p>Node-Red is the front end interface to the bulb.\u00a0 It displays stats that the bulb provides at a set interval.\u00a0 Node-Red also monitors and reports the response from the bulb.\u00a0 There are controls in Node-Red to restart the bulb, check for current time, set or write RGBWW levels to flash memory, and perform firmware updates.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Sunrise.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4492\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Sunrise.png\" alt=\"\" width=\"400\" height=\"281\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Sunrise.png 400w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Sunrise-300x211.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/Sunrise-384x270.png 384w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>Node-Red is used to control the bulb light levels based on scheduling.\u00a0 In the following example, Node-Red mimics the behavior of a sunsrise by fading the bulb on through the color temperature scale.\u00a0 I&#8217;ve done this with a RGBW LED strip in this post, <a href=\"https:\/\/www.cloudacm.com\/?p=4290\">https:\/\/www.cloudacm.com\/?p=4290<\/a><\/p>\n<ul>\n<li>Inject Node &#8211; Repeat at a set time on set days with a defined payload<\/li>\n<li>Looptimer Node &#8211; Loops every 5 seconds for a max of 135 loops, times out after 700 seconds<\/li>\n<li>Function Node &#8211; Adds 1 step to the ColorTemp variable with each loop<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var ColorTemp = context.get(\"counter\") || 0;\r\nColorTemp = (ColorTemp+1);\r\nif(ColorTemp == 136){\r\nmsg.payload = ColorTemp;\r\ncontext.set(\"counter\", 0);\r\nreturn msg;\r\n}    \r\nmsg.payload = ColorTemp;\r\ncontext.set(\"counter\", ColorTemp);\r\nreturn msg;<\/pre>\n<ul>\n<li>Function Node &#8211; Sets the ColorTemp variable to 0 at end of loop<\/li>\n<li>Function Node &#8211; Sets the WarmTemp variable to a set value at end of loop<\/li>\n<li>MQTT Out Node &#8211; Publishes ColorTemp variable from any of the ColorTemp Function Nodes<\/li>\n<li>MQTT Out Node &#8211; Publishes WarmTemp variable from the WarmTemp Function Node<\/li>\n<\/ul>\n<p>The BLF10 and BR30 Kauf RGBWW Smart Bulbs aren&#8217;t too difficult to open and flash.\u00a0 However I did have trouble with the A15 bulbs.\u00a0 I had assumed that the flashing pads would be accessible but found that the LED PCB was layered on top of the ESP8266 PCB.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4224_Cropped.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4493\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4224_Cropped.png\" alt=\"\" width=\"545\" height=\"476\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4224_Cropped.png 545w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4224_Cropped-300x262.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4224_Cropped-309x270.png 309w\" sizes=\"auto, (max-width: 545px) 100vw, 545px\" \/><\/a><\/p>\n<p>Removing the base of the bulb revealed that the hot lead was crimped to the base housing and the converter was wrapped with a single layer of thin tape.\u00a0 Accessing the flash pins would require butchering the upper plastic housing.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4228_Scaled.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4494\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4228_Scaled.png\" alt=\"\" width=\"667\" height=\"375\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4228_Scaled.png 667w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4228_Scaled-300x169.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2023\/09\/IMG_4228_Scaled-480x270.png 480w\" sizes=\"auto, (max-width: 667px) 100vw, 667px\" \/><\/a><\/p>\n<p>This was an unfortunate discovery.\u00a0 If there is a way for me to install my firmware using the stock Kauf OTA firmware, then I might consider using this bulb as well.<\/p>\n<p>All in all, these are interesting devices with the ability to do more than just light a room.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post will provide some experiences with the Kauf RGBWW Smart Bulb and firmware developed with the Arduino IDE.\u00a0 Details about these bulbs can be found on GitHub, https:\/\/github.com\/KaufHA\/kauf-rgbww-bulbs or from the manufacturer&#8217;s website, https:\/\/kaufha.com\/ I referenced this post about the bulb, https:\/\/digiblur.com\/2021\/09\/15\/preflashed-esphome-tasmota-smart-bulbs-with-an-added-bonus-kauf-blf10\/.\u00a0 It mentions that a new firmware can be uploaded through the device web interface.\u00a0 My attempts to upload firmware compiled in the Arduino IDE were not successful. Initially I thought it was an incorrect OTA flash size&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.cloudacm.com\/?p=4420\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4420","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/4420","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4420"}],"version-history":[{"count":60,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/4420\/revisions"}],"predecessor-version":[{"id":4510,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/4420\/revisions\/4510"}],"wp:attachment":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4420"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4420"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4420"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}