Wifi Candle - illuminate with ESPEasy (WS2812)

Moderators: grovkillen, Stuntteam, TD-er

Message
Author
paulymorph
New user
Posts: 8
Joined: 13 Jun 2016, 05:24

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#51 Post by paulymorph » 11 Jan 2017, 00:54

Thank you very much jjansen. This is definitely progress. Already have a quick success using the HTTP method. Now i'll play with the MQTT examples to see if I can get the syntax right.
jjansen wrote:I just saw some additional comments in the source code of the plugin about MQTT
Starting at line 454

Might be useful for you?

paulymorph
New user
Posts: 8
Joined: 13 Jun 2016, 05:24

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#52 Post by paulymorph » 11 Jan 2017, 08:02

SUCCESS!!! I was able to get it all working except for one small thing. I created a Dashboard in Node-Red that can control all the attributes of the Wifi Candle all by sending formatted MQTT messages when I press the button on the dashboard after i have all the settings that I like.

The format for the MQTT message is the following

Topic:
/node2/candle/cmd Node2=device name, candle=The name i gave the Wifi Candle (called "Device" in ESP Easy), cmd= the operator that Moelski wrote into the code.

Message:
COLOR:2:8E3EFF:120 COLOR=static : 2 (Flame Type) : 8E3EFF (Hex color) : 120 (Brightness value 1-255)

1 Static Light, 2 Simple Candle, 3 Advanced Candle, 4 Police, 5 Blink, 6 Strobe, 7 Color Fader

The only thing i couldn't get to work is mode 7 (Color fader). It doesn't seem to work if I try that mode.

I'm glad to share the actual JSON of the flow if anyone is interested.
Screen Shot 2017-01-11 at 12.50.30 AM.png
Screen Shot 2017-01-11 at 12.50.30 AM.png (79.06 KiB) Viewed 49453 times
Screen Shot 2017-01-11 at 12.57.01 AM.png
Screen Shot 2017-01-11 at 12.57.01 AM.png (101.64 KiB) Viewed 49453 times

User avatar
moelski
Normal user
Posts: 161
Joined: 31 Aug 2016, 06:33
Location: Germany - NRW
Contact:

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#53 Post by moelski » 11 Jan 2017, 08:32

Great work Paul.

I think there is one command missing for using default colors or not.
But that is missing in the sources ... I have to add that in the next days.

Anyway ... Your solution looks great.
Personally I use FHEM and I will update my manual for FHEM usage, too.
regards
Dominik

paulymorph
New user
Posts: 8
Joined: 13 Jun 2016, 05:24

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#54 Post by paulymorph » 11 Jan 2017, 21:43

Thanks moelski! I actually have a solution for the default colors... if I send the MQTT payload with nothing in the space for color, it reverts to the default color. Example "COLOR:2::100".

BTW! Do you have an idea why mode 7 doesn't appear to work? It works if I manually change it from the ESP EASY interface (I think). I know it was working on R120 at least.

Thanks

nygma
Normal user
Posts: 25
Joined: 26 Nov 2016, 11:16

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#55 Post by nygma » 18 Jan 2017, 20:41

On a different topic I was asking if a fade function can be made available for the PWM output. Can this candle logic be adapted output the values to 3 GPIOs using PWM instead of neopixel?

medline2c
New user
Posts: 4
Joined: 17 Jan 2017, 00:47

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#56 Post by medline2c » 23 Jan 2017, 13:58

Bonjour !
Félicitations pour ce beau projet... profil bas...
Je suis sur Jeedom avec plugIn EspEasy et je voulais savoir du coup, ayant lu plein de choses sur les ws8212 suite à cet article :
Les librairies ws8212 seraient peu compatibles avec les communications séries (I2C...) : qu'en est-il avec ce programme ? peut-on quand même piloter un afficher LED/OLED ou un lecteur RFID en I2C ou c'est mort...
Autre question : vous me confirmez bien qu'avec la première bibliothèque, je peux néanmoins piloter individuellement des néopixels mais du coup dans la limite de 12 maxi (limitation espeasy sur nombre de devices) ?...
Merci ... je suis ce post avec gourmandise !... bonne continuation !
Christophe

Google traduction :
Hello !
Congratulations for this beautiful project ...
I am on Jeedom with plugIn EspEasy and I wanted to know of the coup, having read many things about the ws8212 following this article:
The libraries ws8212 would be poorly compatible with the serial communications (I2C ...): what is with this program? Can you still drive an LED / OLED display or an RFID reader in I2C or it isn't possible ...
Another question: you confirm to me that with the first library, I can nevertheless drive neopixels but within the limit of 12 maxi (limitation of espeasy on many devices)?
Thank you ... I am this post with gluttony! ... good continuation!
Christophe

Barb232
Normal user
Posts: 40
Joined: 12 Mar 2016, 16:40
Location: Earth
Contact:

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#57 Post by Barb232 » 23 Jan 2017, 14:27

Hi Dominik,

can you send me a link from your manual?
i cant get it working the MQTT and the Candle (using MEGA EasyESP)

groovy
Normal user
Posts: 39
Joined: 14 Oct 2016, 11:32
Location: Chemnitz, Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#58 Post by groovy » 23 Jan 2017, 19:07

I built this candle and it works fine, thanks for sharing!
However, I want to use it with a PIR to enable/disable it when movement is detected.
The whole background and questions can be found on my original post, but maybe here is a better place to ask.
In summary, I want to switch the candle on, when movement is detected and switch it off after a period of time.
Any suggestions?

medline2c
New user
Posts: 4
Joined: 17 Jan 2017, 00:47

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#59 Post by medline2c » 24 Jan 2017, 00:26

Bonsoir !
Je suis en train de tester avec un NodeMCUV1.0.
Cela fonctionne à priori, sauf que lorsque le Node envoie une trame en HTTP à Jeedom, cela stoppe l'animation puis cela repart ensuite.. est-ce normal ? (communication série = interruption ?)
Ensuite, je ne parviens pas à trouver comment piloter via Jeedom la WifiCandle ?... Pouvez-vous m'indiquer la requête HTTP à exécuter ?..
Pour terminer, j'aimerais tester le pilotage d'un NeoPixel en HTTP, comment faire depuis Jeedom étant donné que l'on n'a pas l'option "Send data" quand on choisi ce type de device ?
Merci pour votre aide.
Christophe

Good evening!
I'm trying to test with a NodeMCUV1.0. It seem work good, except when the Node sends an HTTP frame to Jeedom : animation stop and then it starts again .. is this normal? (Serial communication = interruption?)
Then, I can not find how to drive via Jeedom the WifiCandle ... Can you tell me the HTTP request to run ? I've only "info" data send to jeedom but how do the same to the WifiCandle ? I don't understand...
Finally, I would like to test the control of only one NeoPixel with an HTTP command (with NeoPixel Basic installed), how to do withJeedom : I don't find the option "Send data" when choosing this type of device?
Thank you for your help.
Christophe

medline2c
New user
Posts: 4
Joined: 17 Jan 2017, 00:47

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#60 Post by medline2c » 25 Jan 2017, 18:08

Bonsoir,
Je me réponds partiellement à moi même (avis aux débutants tout petit niveau comme moi...) :
J'ai passé plusieurs heures à essayer de comprendre comme tout ça fonctionnait et j'ai réussi par Jeedom à commander la WifiCandle. Il suffit d'inclure dans le plugIn EspEasy la WifiCandle puis d'ajouter dans l'onglet COMMANDES, une commande d'action avec dans la zone "Task et variable" une ligne du style "CANDLE:2::100" pour activer le mode bougie simple avec une luminosité de 100... cela va faire apparaître des boutons pour changer le mode... je n'ai pas trouvé comment faire un curseur pour la couleur mais je cherche...

La question que je me pose toutefois est la suivante :
Etant donné qu'on ne peut gérer d'interruptions, on utilise la fonction millis() ... mais que ce passe-t-il au bout de plusieurs jours d'utilisation, quand la valeur de millis() va revenir à zéro... je n'ai rien vu qui prévoit le cas... :

Code: Select all

Candle_Update = millis() + 150;
(~ligne 402)
J'ai raté quelque chose ?...

Christophe

Good evening,
I respond partially to myself (notice to beginners a little level like me ...):
I spent several hours trying to figure out how it all worked and I managed by Jeedom to order the WifiCandle. It is enough to include in the plugin EspEasy the WifiCandle then to add an action command in the "Task and variable" section of the "CANDLE: 2" :: 100 "to activate the simple candle mode with a brightness of 100 ... this will bring up buttons to change the mode ... I have not found how to make a slider for color but I'm looking for ...

The question I ask myself, however, is this:
Since we can not handle interrupts, we use the function millis () ... but it happens after several days d Use, when the value of millis () will return to zero ... I have not seen anything that provides the case ...:

Code: Select all

 Candle_Update = millis () + 150; 
(~ line 402)
Did I miss something ?...

Christophe

groovy
Normal user
Posts: 39
Joined: 14 Oct 2016, 11:32
Location: Chemnitz, Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#61 Post by groovy » 31 Jan 2017, 08:09

Is it possible to disable saving the settings to flash every time anything is changed?
I'm asking this, because my candle switches on and off many times, so I'm afraid killing the flash really soon.
Can I simply remove these two lines from the code at around line 530?

Code: Select all

SaveTaskSettings(event->TaskIndex);
SaveSettings();
Does this have any other impact? Or should I only remove the second line and leave the first? I'm unsure, so can someone point me at the right direction?

marko67
New user
Posts: 7
Joined: 20 Jan 2017, 06:40

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#62 Post by marko67 » 10 Apr 2017, 17:29

Hello I need your help.
I am using R147 with the extension _p121 candle. A WS2812B strip with 30 neopixel. Is controlled by FHEM.

my question:
How can I control 1-10 led in red 11-20 led in blue and 21-30 led in white control. Is this only with _P122_NeoPixel.ino and if so how?

many thanks for your help

Marko

passie
Normal user
Posts: 20
Joined: 18 Mar 2017, 07:27

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#63 Post by passie » 13 Apr 2017, 13:12

Got the candle working via de esp web gui.
Which command's should be send in order to control the light via mqqt from ex pimatic or any other home automation software ?

I would like to control the led's with an if statement.
So for example:

If temp is > 20 celcius then make the leds red / flash.

-- passie

rolfz
New user
Posts: 3
Joined: 19 Feb 2017, 09:54
Location: Switzerland
Contact:

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#64 Post by rolfz » 25 Apr 2017, 23:44

Just realised that my question was answered on m Post #54.

Hi Paul, great work,

Would it be possible to post the node-red (JSON) code for your solution ? I did not yet get the details about how to setup the message COLOR:2:8E3EFF:120

//Rolf

passie
Normal user
Posts: 20
Joined: 18 Mar 2017, 07:27

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#65 Post by passie » 27 Apr 2017, 09:01

What is the complete mqtt message which has to be send in order to ex. change color ?
Currently i'm able to send mqtt pub to easpeasy like so:

mosquitto_pub -d -h 127.0.0.1 -t mosquitto_pub -h 127.0.0.1 -t /home/candle/Color/cmd -m 'FF0000'
mosquitto_pub -d -h 127.0.0.1 -t mosquitto_pub -h 127.0.0.1 -t /home/candle/Brightness/cmd -m '11'
mosquitto_pub -d -h 127.0.0.1 -t mosquitto_pub -h 127.0.0.1 -t /home/candle/Type/cmd -m '2'

This is working for individual mqtt messages.
But how could i send the complete string to the espeasy so it changes color or do something else ?


Any help would be appreciated.

-- passie

Dylantje
Normal user
Posts: 255
Joined: 11 Oct 2015, 16:51

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#66 Post by Dylantje » 27 Apr 2017, 09:56

Is this option available in the normal EspEasy flash?

passie
Normal user
Posts: 20
Joined: 18 Mar 2017, 07:27

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#67 Post by passie » 29 Apr 2017, 08:52

Dylantje wrote: 27 Apr 2017, 09:56 Is this option available in the normal EspEasy flash?
No it isn't.

passie
Normal user
Posts: 20
Joined: 18 Mar 2017, 07:27

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#68 Post by passie » 29 Apr 2017, 08:57

I'm trying different pub's but i'm unable to get it working via mqtt

Code: Select all

mosquitto_pub -h 127.0.0.1 -t /home/candle/ -m "cmd=CANDLE:1:00FF00:100"
Via a curl I can control the neopixel.

Code: Select all

set_candle_above: 'curl --data "cmd=CANDLE:3:FF0000:200" http://192.168.0.3/control'
Any clue points here ?

artic1980
New user
Posts: 4
Joined: 09 Apr 2017, 17:57

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#69 Post by artic1980 » 30 Apr 2017, 09:35

You can check it through domoticz

passie
Normal user
Posts: 20
Joined: 18 Mar 2017, 07:27

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#70 Post by passie » 30 Apr 2017, 11:08

artic1980 wrote: 30 Apr 2017, 09:35 You can check it through domoticz
I'm trying to send the mqtt pub message not the integration with domoticz!?

helio58
Normal user
Posts: 20
Joined: 11 Mar 2017, 10:21

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#71 Post by helio58 » 28 Jun 2017, 22:43

paulymorph wrote: 11 Jan 2017, 08:02 SUCCESS!!! I was able to get it all working except for one small thing. I created a Dashboard in Node-Red that can control all the attributes of the Wifi Candle all by sending formatted MQTT messages when I press the button on the dashboard after i have all the settings that I like.

The format for the MQTT message is the following

Topic:
/node2/candle/cmd Node2=device name, candle=The name i gave the Wifi Candle (called "Device" in ESP Easy), cmd= the operator that Moelski wrote into the code.

Message:
COLOR:2:8E3EFF:120 COLOR=static : 2 (Flame Type) : 8E3EFF (Hex color) : 120 (Brightness value 1-255)

1 Static Light, 2 Simple Candle, 3 Advanced Candle, 4 Police, 5 Blink, 6 Strobe, 7 Color Fader

The only thing i couldn't get to work is mode 7 (Color fader). It doesn't seem to work if I try that mode.

I'm glad to share the actual JSON of the flow if anyone is interested.

Screen Shot 2017-01-11 at 12.50.30 AM.pngScreen Shot 2017-01-11 at 12.57.01 AM.png
Please could you share the Json of the flow?
Thanks

papperone
Normal user
Posts: 497
Joined: 04 Oct 2016, 23:16

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#72 Post by papperone » 28 Sep 2017, 17:30

I was giving some test to this plugin and I realize I can't get the "color picker" in any on the browser I checked (Chrome, FF, IE and Edge) as shown in the video on the first post.
As well the RGB selct arrows "up/down" are not shown in EDGE while they are in all other browser.

I understand is not a real ESPEasy bug but as far as I can see this plugin is uding java to create special devive page which is not wokring as it shoudl...
Can anyone test it as well? Or maybe better someone that is using this plugin has succeed to get the color picker enabled?
My TINDIE Store where you can find all ESP8266 boards I manufacture --> https://www.tindie.com/stores/GiovanniCas/
My Wiki Project page with self-made PCB/devices --> https://www.letscontrolit.com/wiki/inde ... :Papperone

Speshal
New user
Posts: 1
Joined: 17 Mar 2018, 00:07

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#73 Post by Speshal » 23 Mar 2018, 19:49

jjansen wrote: 10 Jan 2017, 20:03 I just saw some additional comments in the source code of the plugin about MQTT
Starting at line 454

Might be useful for you?

Code: Select all

// Test 
        // MQTT   : mosquitto_pub -d -t sensors/espeasy/ESP_Candle/cmd  -m "CANDLE_OFF"
        // HTTP   : http://192.168.30.183/tools?cmd=CANDLE%3A5%3AFF0000%3A200
        //          http://192.168.30.183/tools?cmd=CANDLE:4:FF0000:200
        // SERIAL : CANDLE:4:FF0000:200<CR><LF>

        // Commands
        // CANDLE:<FlameType>:<Color>:<Brightness>
        //    <FlameType>  : 1 Static Light, 2 Simple Candle, 3 Advanced Candle, 4 Police, 5 Blink, 6 Strobe, 7 Color Fader
        //    <Color>      : n.def.  Use the default color
        //                   RRGGBB  Use color in RRGGBB style (red, green blue) as HEX
        //    <Brightness> : 0-255 
        // Samples:   CANDLE:2::100           Simple Candle with Default color and Brigthness at 100
        //            CANDLE:5:FF0000:200     Blink with RED Color and Brigthness at 200
        //            CANDLE:0::              Candle OFF
        //            CANDLE:1::255           Candle ON - White and full brigthness
Thanks so much for this, it helped me immensely! :D

sjaak538
New user
Posts: 2
Joined: 24 Oct 2016, 18:46

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#74 Post by sjaak538 » 31 Mar 2018, 01:08

Is it possible to make

#define NUM_PIXEL 20 // Defines the amount of LED Pixel
#define NUM_PIXEL_ROW 5 // Defines the amount of LED Pixel per Row

editable in the webform ?

I have a led matrix 8x8 and no programming skills

Thanks in advance

jonathan-orsel
New user
Posts: 1
Joined: 02 May 2018, 05:16

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#75 Post by jonathan-orsel » 02 May 2018, 05:27

Hello,
I made some updates on your plugin for my own usage :
> Led count and column count in plugin configuration (need a restart to apply)
> Some more effects ( find some inspiration at https://www.tweaking4all.com/hardware/a ... p-effects/ )
Feel free to take these changes.
works great with these LED strip https://www.aliexpress.com/item/1m-4m-5 ... autifyAB=0

Code: Select all


#ifdef USES_P042
//#######################################################################################################
//######################################## Plugin 042: NeoPixel Candle ##################################
//#######################################################################################################

// PROJECT INFO
// Wifi Candle for ESPEasy by Dominik Schmidt (10.2016)


// INCLUDE jscolor (http://jscolor.com/)
//   * Download the lib from here: http://jscolor.com/release/latest.zip
//   * Extract jscolor.min.js
//   * Now open the Web UI of your ESPEasy with this URL:
//     http://<IP-ESPEasy>/upload
//   * Select Browse ... and choose the extracted jscolor.min.js File (ensure the ...min... version !!)
//   * Press Upload und you are done.

// Add the Adafruit Neopixel Library to your library path. You will find it here:
// https://github.com/adafruit/Adafruit_NeoPixel
// That´s all :-) Now ESPEasy has a new 25ms "Timer loop" and Neopixel Support.

// NOTES
// Please keep in mind that you can add tasks which produce a very large delay while reading the sensor.
// For example the DS18B20 is very slow in reading the values. This can slow down the simulation and you
// will notice that the candle did not run smooth. So keep an eye on your tasks and don't add to much other tasks.

// HARDWARE
// The Wifi Candle uses 20 WS2812 RGB pixels. They are all connected in one row.
// I build a wooden wick with 5 pixels on each side. (A picture is here : http://www.esp8266.nu/forum/viewtopic.php?f=2&t=2147)
// The pixels are connected to 5V and the data pin I use is GPIO13 (but you can choose another one).
// Please ensure that you use a strong power supply because the pixels consume a lot of power when they
// shine in white with high brightness!
// I also placed a 100µF capacitor at the end of the WS2812 chain on +5/GND just to ensure a good power stability.
// btw ... My Testboard was a NodeMCU V3.

// QUESTIONS
// Send me an email at dominik@logview.info
// or place a comment in the Forum:
// http://www.esp8266.nu/forum/viewtopic.php?f=2&t=2147

// Candle Infos
// http://www.howtodotip.com/how+to+do+arduino+candle++3
// https://codebender.cc/sketch:129316#Neopixel%20Candle.ino
// http://www.instructables.com/id/Garden-Arduino-Lights/?ALLSTEPS                    Garten Beleuchtung
// http://www.instructables.com/id/Arduino-Controlled-Electric-Candle/?ALLSTEPS       InstaMorph Kerze
// https://github.com/danesparza/Halloweenfire/blob/master/halloweenfire.ino          Halloweenfire

// RGB / HSV Converter
// https://github.com/ratkins/RGBConverter          Lib
// https://www.ruinelli.ch/rgb-to-hsv               Code
// http://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both    Code Sammlung

#include <Adafruit_NeoPixel.h>

//#define NUM_PIXEL       150         // Defines the amount of LED Pixel
//#define NUM_PIXEL_ROW    1         // Defines the amount of LED Pixel per Row
int NUM_PIXEL =      150 ;        // Defines the amount of LED Pixel
int NUM_PIXEL_ROW =   1   ;      // Defines the amount of LED Pixel per Row

#define RANDOM_PIXEL    70         // Defines the Flicker Level for Simple Candle
#define BRIGHT_START   128         // Defines the Start Brightness
#define BASE_TEMP       21         // Defines the Base Temp for TempRange Transformation

enum SimType {
  TypeOff,
  TypeSimpleCandle,
  TypeAdvancedCandle,
  TypeStaticLight,
  TypePolice,
  TypeBlink,
  TypeStrobe,
  TypeColorFader,
  TypeCylon,
  TypeSparkle,
  TypeRainbow,
  SIMTYPE_LEN
};

enum ColorType {
  ColorDefault,
  ColorSelected
};

byte Candle_red = 0;
byte Candle_green = 0;
byte Candle_blue = 0;
byte Candle_bright = 128;
SimType Candle_type = TypeSimpleCandle;
ColorType Candle_color = ColorDefault;

// global variables
unsigned long Candle_Update = 0;
word Candle_Temp[4] = { 0, 0, 0 };     // Temp variables
int Candle_Temp4 = 0;
boolean GPIO_Set = false;

Adafruit_NeoPixel *Candle_pixels;

#define PLUGIN_042
#define PLUGIN_ID_042         42
#define PLUGIN_NAME_042       "Output - NeoPixel (Candle)"
#define PLUGIN_VALUENAME1_042 "Color"
#define PLUGIN_VALUENAME2_042 "Brightness"
#define PLUGIN_VALUENAME3_042 "Type"

boolean Plugin_042(byte function, struct EventStruct *event, String& string)
{
  boolean success = false;

  switch (function)
  {

    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_042;
        Device[deviceCount].Type = DEVICE_TYPE_SINGLE;
        Device[deviceCount].VType = SENSOR_TYPE_TRIPLE;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = false;
        Device[deviceCount].FormulaOption = false;
        Device[deviceCount].ValueCount = 3;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = true;
        Device[deviceCount].GlobalSyncOption = false;
        break;
      }

    case PLUGIN_GET_DEVICENAME:
      {
        string = F(PLUGIN_NAME_042);
        break;
      }

    case PLUGIN_GET_DEVICEVALUENAMES:
      {
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_042));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_042));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_042));
        break;
      }

    case PLUGIN_WEBFORM_LOAD:
      {
        string += F("<script src=\"jscolor.min.js\"></script>\n");

        char tmpString[128];
        String options[SIMTYPE_LEN];
        // int optionValues[8];

        options[0] = F("Off");
        options[1] = F("Static Light");
        options[2] = F("Simple Candle");
        options[3] = F("Advanced Candle");
        options[4] = F("Police");
        options[5] = F("Blink");
        options[6] = F("Strobe");
        options[7] = F("Color Fader");
        options[8] = F("Cylon");
        options[9] = F("Sparkle");
        options[10] = F("Rainbow");

        byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][4];
        if (choice > sizeof(options) - 1)
        {
          choice = 2;
        }

        // strip properties selection
        addFormNumericBox(string,F("Led Count"), F("web_Leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][6],1,999);
        addFormNumericBox(string,F("Led per columns"), F("web_Columns"), Settings.TaskDevicePluginConfig[event->TaskIndex][7],1,999);

        // Candle Type Selection
        addFormSelector(string, F("Flame Type"), F("web_Candle_Type"), SIMTYPE_LEN, options, NULL, choice);

        // Advanced Color options
        Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];
        string += F("<TR><TD>Color Handling:<TD>"); // checked
        string += F("<input type='radio' id='web_Color_Default' name='web_Color_Type' value='0'");
        if (Candle_color == ColorDefault) {
          string += F(" checked>");
        } else {
          string += F(">");
        }
        string += F("<label for='web_Color_Default'> Use default color</label><br>");
        string += F("<input type='radio' id='web_Color_Selected' name='web_Color_Type' value='1'");
        if (Candle_color == ColorSelected) {
          string += F(" checked>");
        } else {
          string += F(">");
        }
        string += F("<label for='web_Color_Selected'> Use selected color</label><br>");

        // Color Selection
        char hexvalue[7] = {0};
        sprintf(hexvalue, "%02X%02X%02X",     // Create Hex value for color
                Settings.TaskDevicePluginConfig[event->TaskIndex][0],
                Settings.TaskDevicePluginConfig[event->TaskIndex][1],
                Settings.TaskDevicePluginConfig[event->TaskIndex][2]);

        // http://jscolor.com/examples/
        string += F("<TR><TD>Color:<TD><input class=\"jscolor {onFineChange:'update(this)'}\" value='");
        string += hexvalue;
        string += F("'>");
        addFormNumericBox(string, F("RGB Color"), F("web_RGB_Red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
        addNumericBox(string, F("web_RGB_Green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
        addNumericBox(string, F("web_RGB_Blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);

        // Brightness Selection
        string += F("<TR><TD>Brightness:<TD>min<input type='range' id='web_Bright_Slide' min='0' max='255' value='");
        string += Settings.TaskDevicePluginConfig[event->TaskIndex][3];
        string += F("'> max");

        sprintf_P(tmpString, PSTR("<TR><TD>Brightness Value:<TD><input type='text' name='web_Bright_Text' id='web_Bright_Text' size='3' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
        string += tmpString;

        // Some Javascript we need to update the items
        string += F("<script script type='text/javascript'>");
        string += F("function update(picker) {");
        string += F("    document.getElementById('web_RGB_Red').value = Math.round(picker.rgb[0]);");
        string += F("    document.getElementById('web_RGB_Green').value = Math.round(picker.rgb[1]);");
        string += F("    document.getElementById('web_RGB_Blue').value = Math.round(picker.rgb[2]);");
        string += F("}");
        string += F("</script>");

        string += F("<script type='text/javascript'>window.addEventListener('load', function(){");
        string += F("var slider = document.getElementById('web_Bright_Slide');");
        string += F("slider.addEventListener('change', function(){");
        string += F("document.getElementById('web_Bright_Text').value = this.value;");
        string += F("});");
        string += F("});</script>");

        success = true;
        break;
      }

    case PLUGIN_WEBFORM_SAVE:
      {
        Settings.TaskDevicePluginConfig[event->TaskIndex][6] = getFormItemInt(F("web_Leds"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][7] = getFormItemInt(F("web_Columns"));
        NUM_PIXEL = Settings.TaskDevicePluginConfig[event->TaskIndex][6] ;         // Defines the amount of LED Pixel
        NUM_PIXEL_ROW = Settings.TaskDevicePluginConfig[event->TaskIndex][7];       // Defines the amount of LED Pixel per Row

        Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("web_RGB_Red"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("web_RGB_Green"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("web_RGB_Blue"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][3] = getFormItemInt(F("web_Bright_Text"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][4] = getFormItemInt(F("web_Candle_Type"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][5] = getFormItemInt(F("web_Color_Type"));

        Candle_red = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
        Candle_green = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
        Candle_blue = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
        if (Candle_bright > 255) {
          Candle_bright = 255;
        }
        Candle_bright = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
        Candle_type = (SimType)Settings.TaskDevicePluginConfig[event->TaskIndex][4];
        Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];

        success = true;
        break;
      }

    case PLUGIN_INIT:
      {
        Candle_red = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
        Candle_green = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
        Candle_blue = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
        Candle_bright = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
        NUM_PIXEL = Settings.TaskDevicePluginConfig[event->TaskIndex][6] ;         // Defines the amount of LED Pixel
        NUM_PIXEL_ROW = Settings.TaskDevicePluginConfig[event->TaskIndex][7] ;     // Defines the amount of LED Pixel per Row

        if (Candle_red == 0 && Candle_green == 0 && Candle_blue == 0) {
          Candle_bright = BRIGHT_START;
        }
        Candle_type = (SimType)Settings.TaskDevicePluginConfig[event->TaskIndex][4];
        Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];

        if (!Candle_pixels || GPIO_Set == false)
        {
          GPIO_Set = Settings.TaskDevicePin1[event->TaskIndex] > -1;
          if (Candle_pixels) {
            delete Candle_pixels;
          }
          Candle_pixels = new Adafruit_NeoPixel(NUM_PIXEL, Settings.TaskDevicePin1[event->TaskIndex], NEO_GRB + NEO_KHZ800);
          SetPixelsBlack();
          Candle_pixels->setBrightness(Candle_bright);
          Candle_pixels->begin();
          String log = F("CAND : Init WS2812 Pin : ");
          log += Settings.TaskDevicePin1[event->TaskIndex];
          addLog(LOG_LEVEL_DEBUG, log);
        }

        success = true;
        break;
      }

    case PLUGIN_ONCE_A_SECOND:
      {
        Candle_pixels->setBrightness(Candle_bright);
        Candle_pixels->show(); // This sends the updated pixel color to the hardware.
        success = true;
        break;
      }

    case PLUGIN_FIFTY_PER_SECOND:
      {
        switch (Candle_type)
        {
          case 0:   // "Update" for OFF
            {
              type_Off();
              break;
            }

          case 1:   // Update for LIGHT
            {
              type_Static_Light();
              break;
            }

          case 2: // Random Updates for Simple Candle, Advanced Candle, Fire Simulation
          case 3:
            {
              if (timeOutReached(Candle_Update)) {
                if (Candle_type == 2) {
                  type_Simple_Candle();
                }
                if (Candle_type == 3) {
                  type_Advanced_Candle();
                }
                Candle_Update = millis() + random(25, 150);
              }
              break;
            }

          case 4:   // Update for Police
            {
              if (timeOutReached(Candle_Update)) {
                type_Police();
                Candle_Update = millis() + 150;
              }
              break;
            }

          case 5:   // Update for Blink
            {
              if (timeOutReached(Candle_Update)) {
                type_BlinkStrobe();
                Candle_Update = millis() + 100;
              }
              break;
            }

          case 6:   // Update for Strobe
            {
              type_BlinkStrobe();
              break;
            }
          case 7:   // Update for ColorFader
            {
              if (timeOutReached(Candle_Update)) {
                type_ColorFader();
                Candle_Update = millis() + 2000;
              }
              break;
            }

            //effects addition
          case 8:   // Update for Cylon
            {
              if (timeOutReached(Candle_Update)) {
                type_Cylon(5);
                Candle_Update = millis() + NUM_PIXEL/20;
              }
              break;
            }
            
            case 9:   // Update for type_Sparkle
            {
              type_Sparkle();
              break;
            }
            case 10:   // Update for type_rainbow
            {
              if (timeOutReached(Candle_Update)) {
                type_Rainbow();
                Candle_Update = millis() + 20;
              }
              break;
            }
          
        }

        Candle_pixels->show();

        success = true;
        break;
      }

    case PLUGIN_READ:
      {
        UserVar[event->BaseVarIndex] = Candle_red * 65536 + Candle_green * 256 + Candle_blue;
        UserVar[event->BaseVarIndex + 1] = Candle_bright;
        UserVar[event->BaseVarIndex + 2] = Candle_type;

        success = true;
      }

    case PLUGIN_WRITE:
      {
        String tmpString  = string;

        // Test
        // MQTT   : mosquitto_pub -d -t sensors/espeasy/ESP_Candle/cmd  -m "CANDLE_OFF"
        // HTTP   : http://192.168.30.183/tools?cmd=CANDLE%3A5%3AFF0000%3A200
        //          http://192.168.30.183/tools?cmd=CANDLE:4:FF0000:200
        // SERIAL : CANDLE:4:FF0000:200<CR><LF>

        // Commands
        // CANDLE:<FlameType>:<Color>:<Brightness>
        //    <FlameType>  : 1 Static Light, 2 Simple Candle, 3 Advanced Candle, 4 Police, 5 Blink, 6 Strobe, 7 Color Fader , ...
        //    <Color>      : n.def.  Use the default color
        //                   RRGGBB  Use color in RRGGBB style (red, green blue) as HEX
        //    <Brightness> : 0-255
        // Samples:   CANDLE:2::100           Simple Candle with Default color and Brigthness at 100
        //            CANDLE:5:FF0000:200     Blink with RED Color and Brigthness at 200
        //            CANDLE:0::              Candle OFF
        //            CANDLE:1::255           Candle ON - White and full brigthness

        if (tmpString.startsWith("CANDLE:")){
          int idx1 = tmpString.indexOf(':');
          int idx2 = tmpString.indexOf(':', idx1+1);
          int idx3 = tmpString.indexOf(':', idx2+1);
          int idx4 = tmpString.indexOf(':', idx3+1);
          String val_Type = tmpString.substring(idx1+1, idx2);
          String val_Color = tmpString.substring(idx2+1, idx3);
          String val_Bright = tmpString.substring(idx3+1, idx4);

          if (val_Type != "") {
             if (val_Type.toInt() > -1 && val_Type.toInt() < SIMTYPE_LEN) {
                Settings.TaskDevicePluginConfig[event->TaskIndex][4] = val_Type.toInt();     // Type
                Candle_type = (SimType)Settings.TaskDevicePluginConfig[event->TaskIndex][4];
                String log = F("CAND : CMD - Type : ");
                log += val_Type;
                addLog(LOG_LEVEL_DEBUG, log);
             }
          }

          if (val_Bright != "") {
             if (val_Bright.toInt() > -1 && val_Bright.toInt() < 256) {
                Settings.TaskDevicePluginConfig[event->TaskIndex][3] = val_Bright.toInt();     // Brightness
                Candle_bright = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
                String log = F("CAND : CMD - Bright : ");
                log += val_Bright;
                addLog(LOG_LEVEL_DEBUG, log);
             }
          }

          if (val_Color != "") {
            long number = strtol( &val_Color[0], NULL, 16);
            // Split RGB to r, g, b values
            byte r = number >> 16;
            byte g = number >> 8 & 0xFF;
            byte b = number & 0xFF;

            Settings.TaskDevicePluginConfig[event->TaskIndex][0] = r;   // R
            Settings.TaskDevicePluginConfig[event->TaskIndex][1] = g;   // G
            Settings.TaskDevicePluginConfig[event->TaskIndex][2] = b;   // B
            Candle_red = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
            Candle_green = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
            Candle_blue = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
            Settings.TaskDevicePluginConfig[event->TaskIndex][5] = 1;
            Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];   // ColorType (ColorSelected)

            String log = F("CAND : CMD - R ");
            log += r;
            log += F(" G ");
            log += g;
            log += F(" B ");
            log += b;
            addLog(LOG_LEVEL_DEBUG, log);
          } else {
            Settings.TaskDevicePluginConfig[event->TaskIndex][5] = 0;
            Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];   // ColorType (ColorDefault)
            addLog(LOG_LEVEL_DEBUG, F("CAND : CMD - Color : DEFAULT"));
          }

          //SaveTaskSettings(event->TaskIndex);
          //SaveSettings();

          success = true;
        }

        break;
      }

  }
  return success;
}

void SetPixelsBlack() {
  for (int i = 0; i < NUM_PIXEL; i++) {
    Candle_pixels->setPixelColor(i, Candle_pixels->Color(0, 0, 0));
  }
}

void SetPixelToColor(int PixelIdx) {
  Candle_pixels->setPixelColor(PixelIdx, Candle_pixels->Color(Candle_red, Candle_green, Candle_blue));
}

void type_Off() {
  SetPixelsBlack();
}

void type_Static_Light() {
  for (int i = 0; i < NUM_PIXEL; i++) {
    if (Candle_color == ColorDefault) {
      Candle_pixels->setPixelColor(i, 255, 255, 255);     // Default is white
    } else {
      Candle_pixels->setPixelColor(i, Candle_red, Candle_green, Candle_blue);
    }
  }
}

void type_Simple_Candle() {
  int r, g, b;
  if (Candle_color == ColorDefault) {
    r = 226, g = 042, b =  35;   // Regular (orange) flame
    //r = 158, g =   8, b = 148;   // Purple flame
    //r =  74, g = 150, b =  12;   // Green flame
  } else {
    r = Candle_red, g = Candle_green, b = Candle_blue;
  }

  //  Flicker, based on our initial RGB values
  for (int i = 0; i < NUM_PIXEL; i++) {
    int flicker = random(0, RANDOM_PIXEL);
    int r1 = r - flicker;
    int g1 = g - flicker;
    int b1 = b - flicker;
    if (g1 < 0) g1 = 0;
    if (r1 < 0) r1 = 0;
    if (b1 < 0) b1 = 0;
    Candle_pixels->setPixelColor(i, r1, g1, b1);
  }
}

void type_Advanced_Candle() {
  Candle_Temp[0] = random(1, 4); // 1..4  LEDs in RED
  Candle_Temp[1] = random(1, 4) + Candle_Temp[0]; // 1..3  LEDs in Yellow / Orange
  Candle_Temp[2] = random(0, 2); // 0..1  Choose Yellow = 0 / Orange = 1

  int colorbase[3];
  int color1[3];
  int color2[3];
  int color3[3];

  if (Candle_color == ColorDefault) {
    colorbase[0] = 255; colorbase[1] = 120; colorbase[2] = 0;   // Light Orange #FF7800
    color1[0] = 115; color1[1] = 50; color1[2] = 0;             // Brown      #733200
    color2[0] = 180; color2[1] = 80; color2[2] = 0;             // Orange     #B45000
    color3[0] =  70; color3[1] = 30; color3[2] = 0;              // Dark brown #4A2000
  } else {
    colorbase[0] = Candle_red; colorbase[1] = Candle_green; colorbase[2] = Candle_blue;
    double hsv[3];
    // Calc HSV
    RGBtoHSV(Candle_red, Candle_green, Candle_blue, hsv);
    double newH = hsv[0] - 5;
    if (newH < 0) { newH += 359; }
    double newV = hsv[2] / 2;
    double newV2 = hsv[2] / 4;
    // Calc new RGBs
    HSVtoRGB(newH, hsv[1], hsv[2], color1);
    HSVtoRGB(hsv[0], hsv[1], newV, color2);
    HSVtoRGB(newH, hsv[1], newV2, color3);
  }

  for (int j = 0; j < NUM_PIXEL/5; j++) {
    for (unsigned int i = 1; i < 6; i++){
      if (i <= Candle_Temp[0]) {
        Candle_pixels->setPixelColor(j * 5 + i - 1, colorbase[0], colorbase[1], colorbase[2]);
      }
      if (i > Candle_Temp[0] && i <= Candle_Temp[1]) {
        if (Candle_Temp[2] == 0){
          Candle_pixels->setPixelColor(j * 5 + i - 1, color1[0], color1[1], color1[2]);
        } else {
          Candle_pixels->setPixelColor(j * 5 + i - 1, color2[0], color2[1], color2[2]);
        }
      }
      if (i > Candle_Temp[1]) {
        Candle_pixels->setPixelColor(j * 5 + i - 1, color3[0], color3[1], color3[2]);
      }
    }
  }
}

void type_Police() {
  Candle_Temp[0]++;
  if (Candle_Temp[0] > NUM_PIXEL / 5) {
    Candle_Temp[0] = 0;
  }

  for (unsigned int i = 0; i < NUM_PIXEL / 5; i++) {
    if (i == Candle_Temp[0])
    {
      for (int j = 0; j < 5; j++) {
        if (Candle_color == ColorDefault) {
          Candle_pixels->setPixelColor(i * 5 + j, 0, 0, 255);
        } else {
          Candle_pixels->setPixelColor(i * 5 + j, Candle_red, Candle_green, Candle_blue);
        }
      }
    } else {
      for (int j = 0; j < 5; j++) {
        Candle_pixels->setPixelColor(i * 5 + j, 0, 0, 0);
      }
    }
  }
}

void type_BlinkStrobe() {
  Candle_Temp[0]++;
  if (Candle_Temp[0] > 1) {
    Candle_Temp[0] = 0;
  }

  for (int i = 0; i < NUM_PIXEL; i++) {
    if (Candle_Temp[0] == 0) {
      Candle_pixels->setPixelColor(i, 0, 0, 0);
    } else {
      if (Candle_color == ColorDefault) {
        Candle_pixels->setPixelColor(i, 255, 255, 255);     // Default is white
      } else {
        Candle_pixels->setPixelColor(i, Candle_red, Candle_green, Candle_blue);
      }
    }
  }
}

void type_ColorFader() {
  int colors[3];
  double hsv[3];
  if (Candle_color != ColorDefault) {
    if (Candle_Temp[0] > 254 && Candle_Temp[1] == 1) {
      Candle_Temp[1] = 0;
    }
    if (Candle_Temp[0] < 55 && Candle_Temp[1] == 0) {
      Candle_Temp[1] = 1;
    }

    if (Candle_Temp[1] > 0) {
      Candle_Temp[0]++;
    } else {
      Candle_Temp[0]--;
    }

    // Calc HSV
    // void RGBtoHSV(byte r, byte g, byte b, double hsv[3])
    RGBtoHSV(Candle_red, Candle_green, Candle_blue, hsv);

    // Calc RGB with new V
    // HSVtoRGB(int hue, int sat, int val, int colors[3])
    // hue: 0-359, sat: 0-255, val (lightness): 0-255
    HSVtoRGB(hsv[0], hsv[1], Candle_Temp[0], colors);

    for (int i = 0; i < NUM_PIXEL; i++) {
      Candle_pixels->setPixelColor(i, colors[0], colors[1], colors[2]);
    }
  } else {
    Candle_Temp[0]++;
    if (Candle_Temp[0] > 359) {
      Candle_Temp[0] = 0;
    }

    // hue: 0-359, sat: 0-255, val (lightness): 0-255
    HSVtoRGB(Candle_Temp[0], 255, 255, colors);

    for (int i = 0; i < NUM_PIXEL; i++) {
      Candle_pixels->setPixelColor(i, colors[0], colors[1], colors[2]);
    }
  }
}

// Effects additions
void type_Cylon(int EyeSize){
  byte red = 255; byte green = 255 ; byte blue = 255 ; // Default is white
  if (Candle_color != ColorDefault) {
    red = Candle_red; green = Candle_green ; blue = Candle_blue ;
  }

  if (Candle_Temp[0] >= NUM_PIXEL-EyeSize-1 ) { //max value
    Candle_Temp[1] = 0; //decrease
  } else if (Candle_Temp[0] <=0 ) { //min value
    Candle_Temp[1] = 1; //increase
  }
    if ( Candle_Temp[1] == 0 ) { // decrease
    Candle_Temp[1] = 0;
    Candle_Temp[0]--;
  } else { //increase
    Candle_Temp[1] = 1;
    Candle_Temp[0]++;
  }
  
  for(int i = 0; i < NUM_PIXEL-EyeSize-1; i++) {
    if (Candle_Temp[0]==i) {
      Candle_pixels->setPixelColor(i-1, 0, 0, 0);
      Candle_pixels->setPixelColor(i, red/10, green/10, blue/10);
      for(int j = 1; j <= EyeSize; j++) {
        Candle_pixels->setPixelColor(i+j, red, green, blue);
      }
      Candle_pixels->setPixelColor(i+EyeSize+1, red/10, green/10, blue/10);
      Candle_pixels->setPixelColor(i+EyeSize+2, 0, 0, 0);
    }
  }
}

void type_Sparkle() {
  byte red = 255; byte green = 255 ; byte blue = 255 ; // Default is white
  if (Candle_color != ColorDefault) {
    red = Candle_red; green = Candle_green ; blue = Candle_blue ;
  }
  int Pixel ;
  for (int i=0 ; i<10; i++)
  {
    Pixel = random(NUM_PIXEL);
    Candle_pixels->setPixelColor(Pixel,red,green,blue);
    Pixel = random(NUM_PIXEL);
    Candle_pixels->setPixelColor(Pixel,0,0,0);
  }
}


void type_Rainbow() {
  byte *c;
  uint16_t i;
  
  //for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
  Candle_Temp[0]++ ;
  if (Candle_Temp[0] > 256*5 ) Candle_Temp[0] = 0;
  
  for(i=0; i< NUM_PIXEL; i++) {
    c=Wheel(((i * 256 / NUM_PIXEL) + Candle_Temp[0]) & 255);
    Candle_pixels->setPixelColor(i, *c, *(c+1), *(c+2));
  }
}

byte * Wheel(byte WheelPos) {
  static byte c[3];
  if(WheelPos < 85) {
   c[0]=WheelPos * 3;
   c[1]=255 - WheelPos * 3;
   c[2]=0;
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   c[0]=255 - WheelPos * 3;
   c[1]=0;
   c[2]=WheelPos * 3;
  } else {
   WheelPos -= 170;
   c[0]=0;
   c[1]=WheelPos * 3;
   c[2]=255 - WheelPos * 3;
  }
  return c;
}


// Convert HSC Color to RGB Color
void HSVtoRGB(int hue, int sat, int val, int colors[3]) {
  // hue: 0-359, sat: 0-255, val (lightness): 0-255
  int r=0, g=0, b=0, base=0;

  if (sat == 0) { // Achromatic color (gray).
    colors[0]=val;
    colors[1]=val;
    colors[2]=val;
  }
  else  {
    base = ((255 - sat) * val)>>8;
    switch(hue/60) {
    case 0:
      r = val;
      g = (((val-base)*hue)/60)+base;
      b = base;
      break;
    case 1:
      r = (((val-base)*(60-(hue%60)))/60)+base;
      g = val;
      b = base;
      break;
    case 2:
      r = base;
      g = val;
      b = (((val-base)*(hue%60))/60)+base;
      break;
    case 3:
      r = base;
      g = (((val-base)*(60-(hue%60)))/60)+base;
      b = val;
      break;
    case 4:
      r = (((val-base)*(hue%60))/60)+base;
      g = base;
      b = val;
      break;
    case 5:
      r = val;
      g = base;
      b = (((val-base)*(60-(hue%60)))/60)+base;
      break;
    }
    colors[0]=r;
    colors[1]=g;
    colors[2]=b;
  }
}

// Convert RGB Color to HSV Color
void RGBtoHSV(byte r, byte g, byte b, double hsv[3]) {
    double rd = (double) r/255;
    double gd = (double) g/255;
    double bd = (double) b/255;
    double maxval = rd;
    if (gd > maxval) { maxval = gd; }
    if (bd > maxval) { maxval = bd; }
    double minval = rd;
    if (gd < minval) { minval = gd; }
    if (bd < minval) { minval = bd; }
    double h = 0, s, v = maxval;
    double d = maxval - minval;

    s = maxval == 0 ? 0 : d / maxval;

    if (maxval == minval) {
        h = 0; // achromatic
    } else {
        if (maxval == rd) {
            h = (gd - bd) / d + (gd < bd ? 6 : 0);
        } else if (maxval == gd) {
            h = (bd - rd) / d + 2;
        } else if (maxval == bd) {
            h = (rd - gd) / d + 4;
        }
        h /= 6;
    }

    hsv[0] = h * 360;
    hsv[1] = s * 255;
    hsv[2] = v * 255;
}
#endif // USES_P042

riker1
Normal user
Posts: 344
Joined: 26 Dec 2017, 18:02

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#76 Post by riker1 » 24 May 2018, 09:51

jonathan-orsel wrote: 02 May 2018, 05:27 Hello,
I made some updates on your plugin for my own usage :
> Led count and column count in plugin configuration (need a restart to apply)

Hi
is this integrated in a special firmware?
Thanks T

papperone
Normal user
Posts: 497
Joined: 04 Oct 2016, 23:16

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#77 Post by papperone » 24 May 2018, 14:02

jonathan-orsel wrote: 02 May 2018, 05:27 Hello,
I made some updates on your plugin for my own usage :
> Led count and column count in plugin configuration (need a restart to apply)
> Some more effects ( find some inspiration at https://www.tweaking4all.com/hardware/a ... p-effects/ )
Feel free to take these changes.
works great with these LED strip https://www.aliexpress.com/item/1m-4m-5 ... autifyAB=0
why you don't submit those changes in the GitHub repository? I think it is a very good improvement for this plugin which is part of the 2.0 release...
My TINDIE Store where you can find all ESP8266 boards I manufacture --> https://www.tindie.com/stores/GiovanniCas/
My Wiki Project page with self-made PCB/devices --> https://www.letscontrolit.com/wiki/inde ... :Papperone

kiwijunglist
New user
Posts: 6
Joined: 14 Jun 2018, 01:26

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#78 Post by kiwijunglist » 14 Jun 2018, 02:56

Can someone tell me how to issue mqtt commands to espeasy using openhab protocol.

Device name = esp01
Subscribe template = /%sysname%/
Task -> Device: switch
Task -> Device name: led
Task -> Device GPIO: 14
Task -> Device optional name: switch

http://192.168.178.100/control?cmd=GPIO,14,0 and http://192.168.178.100/control?cmd=GPIO,14,1 are working for turning the LED light on and off

MQTT subscription works fine, but MQTT publish commands to control the esp chip doesn't work!

What would the mqtt topic and command for controlling this LED? I spent 2 hours trying different combinations.

PLEASE SOMEONE HELP ME !!!! :( :( :(

teqilla
New user
Posts: 1
Joined: 27 Jul 2018, 19:11

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#79 Post by teqilla » 27 Jul 2018, 19:14

Meybe someone give me a code for Home Assistant to control wifi candle thru mqtt.
Thanx in advance.

Reefie
New user
Posts: 6
Joined: 03 Oct 2018, 20:12

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#80 Post by Reefie » 03 Oct 2018, 20:25

Hi Paul
paulymorph wrote: 11 Jan 2017, 08:02 SUCCESS!!! I was able to get it all working except for one small thing. I created a Dashboard in Node-Red that can control all the attributes of the Wifi Candle all by sending formatted MQTT messages when I press the button on the dashboard after i have all the settings that I like.


I'm glad to share the actual JSON of the flow if anyone is interested.
I realise it has been quite some time since you posted this, I was wondering if you still had the flow and if so, would you mind sharing :P

anthony420
New user
Posts: 4
Joined: 14 Oct 2017, 03:08

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#81 Post by anthony420 » 10 Oct 2018, 02:30

For anyone interested, I created a circuit board for use with this plugin.

Uses APA 106 Neopixel LEDs (preferably 5mm as 8mm may not fit)
Positions for 0.1uF decoupling capacitors in 1206 SMD size
Position for large (1000uf) electrolytic filter cap on 5V input
Designed to be cascaded.

I had these built by JLCPCB and they work fine.
Board design can be found here.. https://easyeda.com/anthony.calia/indiv ... -led-board

Let me know if you use it successfully or have ideas for improvement

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#82 Post by tozett » 10 Oct 2018, 07:29

maybe an illustrating picture of your candles?

:D

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#83 Post by tozett » 10 Oct 2018, 08:18

jonathan-orsel wrote: 02 May 2018, 05:27 Hello,
I made some updates on your plugin for my own usage :
> Led count and column count in plugin configuration (need a restart to apply)
> Some more effects ( find some inspiration at https://www.tweaking4all.com/hardware/a ... p-effects/ )
Feel free to take these changes.

can anybody tell if the devs put this in the last automatic builds,
or do i have to compile this myself into espeasy at 2018-10-10 ?

thanks, guys,
tozett

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#84 Post by tozett » 10 Oct 2018, 10:49

jonathan-orsel wrote: 02 May 2018, 05:27 Hello,
I made some updates on your plugin for my own usage :
> Led count and column count in plugin configuration (need a restart to apply)
> Some more effects ( find some inspiration at https://www.tweaking4all.com/hardware/a ... p-effects/ )
Feel free to take these changes.

Code: Select all


#ifdef USES_P042
//#######################################################################################################
//######################################## Plugin 042: NeoPixel Candle ##################################
}
#endif // USES_P042
Hi, i tried to compile with espeasy source 20181002. but i got errors.
without your source (i mean the original plugin-code) compiles and runs without hassle.

could you give me a hint, what to fix?

Code: Select all

:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\_P042_Candle.ino: In function 'boolean Plugin_042(byte, EventStruct*, String&)':

_P042_Candle:171: error: no matching function for call to 'addFormNumericBox(String&, const __FlashStringHelper*, const __FlashStringHelper*, int16_t&, int, int)'

         addFormNumericBox(string,F("Led Count"), F("web_Leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][6],1,999);

                                                                                                                           ^

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\_P042_Candle.ino:171:123: note: candidates are:

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\WebServer.ino:2930:6: note: void addFormNumericBox(const String&, const String&, int, int, int)

 void addFormNumericBox(const String& label, const String& id, int value, int min, int max)

      ^

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\WebServer.ino:2930:6: note:   candidate expects 5 arguments, 6 provided

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\WebServer.ino:2936:6: note: void addFormNumericBox(const String&, const String&, int)

 void addFormNumericBox(const String& label, const String& id, int value)

      ^

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\WebServer.ino:2936:6: note:   candidate expects 3 arguments, 6 provided

_P042_Candle:172: error: no matching function for call to 'addFormNumericBox(String&, const __FlashStringHelper*, const __FlashStringHelper*, int16_t&, int, int)'

         addFormNumericBox(string,F("Led per columns"), F("web_Columns"), Settings.TaskDevicePluginConfig[event->TaskIndex][7],1,999);


TD-er
Core team member
Posts: 8607
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#85 Post by TD-er » 10 Oct 2018, 12:16

Remove the first entry (the string) of the calls to these functions in your ino file.

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#86 Post by tozett » 10 Oct 2018, 12:23

I am Not Sure, What to Change in the Code exactly. I can Experiment later with your hint.

Anyway Thanks for quick Response

(Mobile Edited), tozett

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#87 Post by tozett » 10 Oct 2018, 16:08

TD-er wrote: 10 Oct 2018, 12:16 Remove the first entry (the string) of the calls to these functions in your ino file.
Thanks, i removed the "string" word, these errors are gone.

the code seems to need somehow some polish, but it compiled to the end.
maybe these errors/warings can be re-coded to better code?

Code: Select all

:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\_P042_Candle.ino: In function 'boolean Plugin_042(byte, EventStruct*, String&)':

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\_P042_Candle.ino:318:16: warning: enumeration value 'SIMTYPE_LEN' not handled in switch [-Wswitch]

         switch (Candle_type)

                ^

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\_P042_Candle.ino: In function 'void type_Police()':

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\sketches\ESPEasy\_P042_Candle.ino:614:44: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

   for (unsigned int i = 0; i < NUM_PIXEL / 5; i++) {

                                            ^
and second:

Code: Select all

:\daten\olaf.arduino\arduino-1.6.11mega20181002\libraries\AS_BH1750\AS_BH1750A.cpp: In member function 'bool AS_BH1750A::startMeasurementAsync(TimeFuncPtr)':

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\libraries\AS_BH1750\AS_BH1750A.cpp:518:7: warning: unused variable '_lastResult' [-Wunused-variable]

   int _lastResult = -1;

       ^

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\libraries\AS_BH1750\AS_BH1750A.cpp: In member function 'bool AS_BH1750A::delayExpired()':

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\libraries\AS_BH1750\AS_BH1750A.cpp:533:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

   if (timestamp < _lastTimestamp)

                   ^

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\libraries\AS_BH1750\AS_BH1750A.cpp:536:45: warning: statement has no effect [-Wunused-value]

     delayTime = MAX_U_LONG - _lastTimestamp + timestamp;

                                             ^

D:\daten\olaf.arduino\arduino-1.6.11mega20181002\libraries\AS_BH1750\AS_BH1750A.cpp:542:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

   return (delayTime >= _nextDelay);

                        ^


tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#88 Post by tozett » 10 Oct 2018, 16:23

Bug in PLUGIN_WEBFORM_LOAD, should not append to string, use addHtml() instead

i also discoverd a web-error in the (patched) plugin 042.
again, i dont know where to look, the source seems big meanwhile...


and it does not work :cry: :cry:
Attachments
esp002.png
esp002.png (196.47 KiB) Viewed 39132 times

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#89 Post by tozett » 10 Oct 2018, 16:31

this is the place with the error, but what to do?
(sadly, i am no coder...) :cry: :cry:
Attachments
esp003.png
esp003.png (67.41 KiB) Viewed 38870 times

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#90 Post by tozett » 10 Oct 2018, 17:18

i used my brain, exhanged the old string += "" method with addhtml(),
and it works now.

the waring about symtype_len seems to me ignorable,
i googled it and it seem to be a coder-trick to get the length of the enum.

as far as it is working at the moment, i am happy. :D
lets see, how many updates we can go with it..
Attachments
esp04.png
esp04.png (236.17 KiB) Viewed 38869 times

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#91 Post by tozett » 10 Oct 2018, 17:20

version from 2018/10/10, running with espeasy source 20181002:
(i first had a bug in the brightness-value web-form. but here it is fixed):

Code: Select all


#ifdef USES_P042
//#######################################################################################################
//######################################## Plugin 042: NeoPixel Candle ##################################
//#######################################################################################################

// PROJECT INFO
// Wifi Candle for ESPEasy by Dominik Schmidt (10.2016)


// INCLUDE jscolor (http://jscolor.com/)
//   * Download the lib from here: http://jscolor.com/release/latest.zip
//   * Extract jscolor.min.js
//   * Now open the Web UI of your ESPEasy with this URL:
//     http://<IP-ESPEasy>/upload
//   * Select Browse ... and choose the extracted jscolor.min.js File (ensure the ...min... version !!)
//   * Press Upload und you are done.

// Add the Adafruit Neopixel Library to your library path. You will find it here:
// https://github.com/adafruit/Adafruit_NeoPixel
// That´s all :-) Now ESPEasy has a new 25ms "Timer loop" and Neopixel Support.

// NOTES
// Please keep in mind that you can add tasks which produce a very large delay while reading the sensor.
// For example the DS18B20 is very slow in reading the values. This can slow down the simulation and you
// will notice that the candle did not run smooth. So keep an eye on your tasks and don't add to much other tasks.

// HARDWARE
// The Wifi Candle uses 20 WS2812 RGB pixels. They are all connected in one row.
// I build a wooden wick with 5 pixels on each side. (A picture is here : http://www.esp8266.nu/forum/viewtopic.php?f=2&t=2147)
// The pixels are connected to 5V and the data pin I use is GPIO13 (but you can choose another one).
// Please ensure that you use a strong power supply because the pixels consume a lot of power when they
// shine in white with high brightness!
// I also placed a 100µF capacitor at the end of the WS2812 chain on +5/GND just to ensure a good power stability.
// btw ... My Testboard was a NodeMCU V3.

// QUESTIONS
// Send me an email at dominik@logview.info
// or place a comment in the Forum:
// http://www.esp8266.nu/forum/viewtopic.php?f=2&t=2147

// Candle Infos
// http://www.howtodotip.com/how+to+do+arduino+candle++3
// https://codebender.cc/sketch:129316#Neopixel%20Candle.ino
// http://www.instructables.com/id/Garden-Arduino-Lights/?ALLSTEPS                    Garten Beleuchtung
// http://www.instructables.com/id/Arduino-Controlled-Electric-Candle/?ALLSTEPS       InstaMorph Kerze
// https://github.com/danesparza/Halloweenfire/blob/master/halloweenfire.ino          Halloweenfire

// RGB / HSV Converter
// https://github.com/ratkins/RGBConverter          Lib
// https://www.ruinelli.ch/rgb-to-hsv               Code
// http://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both    Code Sammlung

#include <Adafruit_NeoPixel.h>

//#define NUM_PIXEL       150         // Defines the amount of LED Pixel
//#define NUM_PIXEL_ROW    1         // Defines the amount of LED Pixel per Row
int NUM_PIXEL =      150 ;        // Defines the amount of LED Pixel
int NUM_PIXEL_ROW =   1   ;      // Defines the amount of LED Pixel per Row

#define RANDOM_PIXEL    70         // Defines the Flicker Level for Simple Candle
#define BRIGHT_START   128         // Defines the Start Brightness
#define BASE_TEMP       21         // Defines the Base Temp for TempRange Transformation

enum SimType {
  TypeOff,
  TypeSimpleCandle,
  TypeAdvancedCandle,
  TypeStaticLight,
  TypePolice,
  TypeBlink,
  TypeStrobe,
  TypeColorFader,
  TypeCylon,
  TypeSparkle,
  TypeRainbow,
  SIMTYPE_LEN
};

enum ColorType {
  ColorDefault,
  ColorSelected
};

byte Candle_red = 0;
byte Candle_green = 0;
byte Candle_blue = 0;
byte Candle_bright = 128;
SimType Candle_type = TypeSimpleCandle;
ColorType Candle_color = ColorDefault;

// global variables
unsigned long Candle_Update = 0;
word Candle_Temp[4] = { 0, 0, 0 };     // Temp variables
int Candle_Temp4 = 0;
boolean GPIO_Set = false;

Adafruit_NeoPixel *Candle_pixels;

#define PLUGIN_042
#define PLUGIN_ID_042         42
#define PLUGIN_NAME_042       "Output - NeoPixel (Candle)"
#define PLUGIN_VALUENAME1_042 "Color"
#define PLUGIN_VALUENAME2_042 "Brightness"
#define PLUGIN_VALUENAME3_042 "Type"

boolean Plugin_042(byte function, struct EventStruct *event, String& string)
{
  boolean success = false;

  switch (function)
  {

    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_042;
        Device[deviceCount].Type = DEVICE_TYPE_SINGLE;
        Device[deviceCount].VType = SENSOR_TYPE_TRIPLE;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = false;
        Device[deviceCount].FormulaOption = false;
        Device[deviceCount].ValueCount = 3;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = true;
        Device[deviceCount].GlobalSyncOption = false;
        break;
      }

    case PLUGIN_GET_DEVICENAME:
      {
        string = F(PLUGIN_NAME_042);
        break;
      }

    case PLUGIN_GET_DEVICEVALUENAMES:
      {
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_042));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_042));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_042));
        break;
      }

    case PLUGIN_WEBFORM_LOAD:
      {
        addHtml(F("<script src=\"jscolor.min.js\"></script>\n"));

        char tmpString[128];
        String options[SIMTYPE_LEN];
        // int optionValues[8];

        options[0] = F("Off");
        options[1] = F("Static Light");
        options[2] = F("Simple Candle");
        options[3] = F("Advanced Candle");
        options[4] = F("Police");
        options[5] = F("Blink");
        options[6] = F("Strobe");
        options[7] = F("Color Fader");
        options[8] = F("Cylon");
        options[9] = F("Sparkle");
        options[10] = F("Rainbow");

        byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][4];
        if (choice > sizeof(options) - 1)
        {
          choice = 2;
        }

        // strip properties selection
        //addFormNumericBox(string,F("Led Count"), F("web_Leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][6],1,999);
        addFormNumericBox(F("Led Count"), F("web_Leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][6],1,999);
        //addFormNumericBox(string,F("Led per columns"), F("web_Columns"), Settings.TaskDevicePluginConfig[event->TaskIndex][7],1,999);
        addFormNumericBox(F("Led per columns"), F("web_Columns"), Settings.TaskDevicePluginConfig[event->TaskIndex][7],1,999);

        // Candle Type Selection
        //addFormSelector(string, F("Flame Type"), F("web_Candle_Type"), SIMTYPE_LEN, options, NULL, choice);
        addFormSelector(F("Flame Type"), F("web_Candle_Type"), SIMTYPE_LEN, options, NULL, choice);

        // Advanced Color options
        Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];
        addHtml(F("<TR><TD>Color Handling:<TD>")); // checked
        addHtml(F("<input type='radio' id='web_Color_Default' name='web_Color_Type' value='0'"));
        if (Candle_color == ColorDefault) {
          addHtml(F(" checked>"));
        } else {
          addHtml(F(">"));
        }
        addHtml(("<label for='web_Color_Default'> Use default color</label><br>"));
        addHtml(("<input type='radio' id='web_Color_Selected' name='web_Color_Type' value='1'"));
        if (Candle_color == ColorSelected) {
          addHtml(F(" checked>"));
        } else {
          addHtml(F(">"));
        }
        addHtml(F("<label for='web_Color_Selected'> Use selected color</label><br>"));

        // Color Selection
        char hexvalue[7] = {0};
        sprintf(hexvalue, "%02X%02X%02X",     // Create Hex value for color
                Settings.TaskDevicePluginConfig[event->TaskIndex][0],
                Settings.TaskDevicePluginConfig[event->TaskIndex][1],
                Settings.TaskDevicePluginConfig[event->TaskIndex][2]);

        // http://jscolor.com/examples/
        addHtml(F("<TR><TD>Color:<TD><input class=\"jscolor {onFineChange:'update(this)'}\" value='"));
        addHtml(hexvalue);
        addHtml(F("'>"));
        //addFormNumericBox(string, F("RGB Color"), F("web_RGB_Red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
        //addNumericBox(string, F("web_RGB_Green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
        //addNumericBox(string, F("web_RGB_Blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
        addFormNumericBox(F("RGB Color"), F("web_RGB_Red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
        addNumericBox(F("web_RGB_Green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
        addNumericBox(F("web_RGB_Blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);



        // Brightness Selection
        //addHtml(F("<TR><TD>Brightness:<TD>min<input type='range' id='web_Bright_Slide' min='0' max='255' value='"));
        //addHtml(Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
        //addHtml(F("'> max"));
        
        //sprintf_P(tmpString, PSTR("<TR><TD>Brightness:<TD>min<input type='range' id='web_Bright_Slide' min='0' max='255' value='"), Settings.TaskDevicePluginConfig[event->TaskIndex][3],"'> max");
        //addHtml(tmpString);

        //sprintf_P(tmpString, PSTR("<TR><TD>Brightness Value:<TD><input type='text' name='web_Bright_Text' id='web_Bright_Text' size='3' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
        //addHtml(tmpString);

         // Brightness Selection
        addHtml(F("<TR><TD>Brightness:<TD>min<input type='range' id='web_Bright_Slide' min='0' max='255' value='"));
        addHtml(String(Settings.TaskDevicePluginConfig[event->TaskIndex][3]));
        addHtml(F("'> max"));

        sprintf_P(tmpString, PSTR("<TR><TD>Brightness Value:<TD><input type='text' name='web_Bright_Text' id='web_Bright_Text' size='3' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
        addHtml(tmpString);

        // Some Javascript we need to update the items
        addHtml(F("<script script type='text/javascript'>"));
        addHtml(F("function update(picker) {"));
        addHtml(F("    document.getElementById('web_RGB_Red').value = Math.round(picker.rgb[0]);"));
        addHtml(F("    document.getElementById('web_RGB_Green').value = Math.round(picker.rgb[1]);"));
        addHtml(F("    document.getElementById('web_RGB_Blue').value = Math.round(picker.rgb[2]);"));
        addHtml(F("}"));
        addHtml(F("</script>"));

        addHtml(F("<script type='text/javascript'>window.addEventListener('load', function(){"));
        addHtml(F("var slider = document.getElementById('web_Bright_Slide');"));
        addHtml(F("slider.addEventListener('change', function(){"));
        addHtml(F("document.getElementById('web_Bright_Text').value = this.value;"));
        addHtml(F("});"));
        addHtml(F("});</script>"));

        success = true;
        break;
      }

    case PLUGIN_WEBFORM_SAVE:
      {
        Settings.TaskDevicePluginConfig[event->TaskIndex][6] = getFormItemInt(F("web_Leds"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][7] = getFormItemInt(F("web_Columns"));
        NUM_PIXEL = Settings.TaskDevicePluginConfig[event->TaskIndex][6] ;         // Defines the amount of LED Pixel
        NUM_PIXEL_ROW = Settings.TaskDevicePluginConfig[event->TaskIndex][7];       // Defines the amount of LED Pixel per Row

        Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("web_RGB_Red"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("web_RGB_Green"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("web_RGB_Blue"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][3] = getFormItemInt(F("web_Bright_Text"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][4] = getFormItemInt(F("web_Candle_Type"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][5] = getFormItemInt(F("web_Color_Type"));

        Candle_red = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
        Candle_green = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
        Candle_blue = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
        if (Candle_bright > 255) {
          Candle_bright = 255;
        }
        Candle_bright = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
        Candle_type = (SimType)Settings.TaskDevicePluginConfig[event->TaskIndex][4];
        Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];

        success = true;
        break;
      }

    case PLUGIN_INIT:
      {
        Candle_red = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
        Candle_green = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
        Candle_blue = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
        Candle_bright = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
        NUM_PIXEL = Settings.TaskDevicePluginConfig[event->TaskIndex][6] ;         // Defines the amount of LED Pixel
        NUM_PIXEL_ROW = Settings.TaskDevicePluginConfig[event->TaskIndex][7] ;     // Defines the amount of LED Pixel per Row

        if (Candle_red == 0 && Candle_green == 0 && Candle_blue == 0) {
          Candle_bright = BRIGHT_START;
        }
        Candle_type = (SimType)Settings.TaskDevicePluginConfig[event->TaskIndex][4];
        Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];

        if (!Candle_pixels || GPIO_Set == false)
        {
          GPIO_Set = Settings.TaskDevicePin1[event->TaskIndex] > -1;
          if (Candle_pixels) {
            delete Candle_pixels;
          }
          Candle_pixels = new Adafruit_NeoPixel(NUM_PIXEL, Settings.TaskDevicePin1[event->TaskIndex], NEO_GRB + NEO_KHZ800);
          SetPixelsBlack();
          Candle_pixels->setBrightness(Candle_bright);
          Candle_pixels->begin();
          String log = F("CAND : Init WS2812 Pin : ");
          log += Settings.TaskDevicePin1[event->TaskIndex];
          addLog(LOG_LEVEL_DEBUG, log);
        }

        success = true;
        break;
      }

    case PLUGIN_ONCE_A_SECOND:
      {
        Candle_pixels->setBrightness(Candle_bright);
        Candle_pixels->show(); // This sends the updated pixel color to the hardware.
        success = true;
        break;
      }

    case PLUGIN_FIFTY_PER_SECOND:
      {
        switch (Candle_type)
        {
          case 0:   // "Update" for OFF
            {
              type_Off();
              break;
            }

          case 1:   // Update for LIGHT
            {
              type_Static_Light();
              break;
            }

          case 2: // Random Updates for Simple Candle, Advanced Candle, Fire Simulation
          case 3:
            {
              if (timeOutReached(Candle_Update)) {
                if (Candle_type == 2) {
                  type_Simple_Candle();
                }
                if (Candle_type == 3) {
                  type_Advanced_Candle();
                }
                Candle_Update = millis() + random(25, 150);
              }
              break;
            }

          case 4:   // Update for Police
            {
              if (timeOutReached(Candle_Update)) {
                type_Police();
                Candle_Update = millis() + 150;
              }
              break;
            }

          case 5:   // Update for Blink
            {
              if (timeOutReached(Candle_Update)) {
                type_BlinkStrobe();
                Candle_Update = millis() + 100;
              }
              break;
            }

          case 6:   // Update for Strobe
            {
              type_BlinkStrobe();
              break;
            }
          case 7:   // Update for ColorFader
            {
              if (timeOutReached(Candle_Update)) {
                type_ColorFader();
                Candle_Update = millis() + 2000;
              }
              break;
            }

            //effects addition
          case 8:   // Update for Cylon
            {
              if (timeOutReached(Candle_Update)) {
                type_Cylon(5);
                Candle_Update = millis() + NUM_PIXEL/20;
              }
              break;
            }
            
            case 9:   // Update for type_Sparkle
            {
              type_Sparkle();
              break;
            }
            case 10:   // Update for type_rainbow
            {
              if (timeOutReached(Candle_Update)) {
                type_Rainbow();
                Candle_Update = millis() + 20;
              }
              break;
            }
          
        }

        Candle_pixels->show();

        success = true;
        break;
      }

    case PLUGIN_READ:
      {
        UserVar[event->BaseVarIndex] = Candle_red * 65536 + Candle_green * 256 + Candle_blue;
        UserVar[event->BaseVarIndex + 1] = Candle_bright;
        UserVar[event->BaseVarIndex + 2] = Candle_type;

        success = true;
      }

    case PLUGIN_WRITE:
      {
        String tmpString  = string;

        // Test
        // MQTT   : mosquitto_pub -d -t sensors/espeasy/ESP_Candle/cmd  -m "CANDLE_OFF"
        // HTTP   : http://192.168.30.183/tools?cmd=CANDLE%3A5%3AFF0000%3A200
        //          http://192.168.30.183/tools?cmd=CANDLE:4:FF0000:200
        // SERIAL : CANDLE:4:FF0000:200<CR><LF>

        // Commands
        // CANDLE:<FlameType>:<Color>:<Brightness>
        //    <FlameType>  : 1 Static Light, 2 Simple Candle, 3 Advanced Candle, 4 Police, 5 Blink, 6 Strobe, 7 Color Fader , ...
        //    <Color>      : n.def.  Use the default color
        //                   RRGGBB  Use color in RRGGBB style (red, green blue) as HEX
        //    <Brightness> : 0-255
        // Samples:   CANDLE:2::100           Simple Candle with Default color and Brigthness at 100
        //            CANDLE:5:FF0000:200     Blink with RED Color and Brigthness at 200
        //            CANDLE:0::              Candle OFF
        //            CANDLE:1::255           Candle ON - White and full brigthness

        if (tmpString.startsWith("CANDLE:")){
          int idx1 = tmpString.indexOf(':');
          int idx2 = tmpString.indexOf(':', idx1+1);
          int idx3 = tmpString.indexOf(':', idx2+1);
          int idx4 = tmpString.indexOf(':', idx3+1);
          String val_Type = tmpString.substring(idx1+1, idx2);
          String val_Color = tmpString.substring(idx2+1, idx3);
          String val_Bright = tmpString.substring(idx3+1, idx4);

          if (val_Type != "") {
             if (val_Type.toInt() > -1 && val_Type.toInt() < SIMTYPE_LEN) {
                Settings.TaskDevicePluginConfig[event->TaskIndex][4] = val_Type.toInt();     // Type
                Candle_type = (SimType)Settings.TaskDevicePluginConfig[event->TaskIndex][4];
                String log = F("CAND : CMD - Type : ");
                log += val_Type;
                addLog(LOG_LEVEL_DEBUG, log);
             }
          }

          if (val_Bright != "") {
             if (val_Bright.toInt() > -1 && val_Bright.toInt() < 256) {
                Settings.TaskDevicePluginConfig[event->TaskIndex][3] = val_Bright.toInt();     // Brightness
                Candle_bright = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
                String log = F("CAND : CMD - Bright : ");
                log += val_Bright;
                addLog(LOG_LEVEL_DEBUG, log);
             }
          }

          if (val_Color != "") {
            long number = strtol( &val_Color[0], NULL, 16);
            // Split RGB to r, g, b values
            byte r = number >> 16;
            byte g = number >> 8 & 0xFF;
            byte b = number & 0xFF;

            Settings.TaskDevicePluginConfig[event->TaskIndex][0] = r;   // R
            Settings.TaskDevicePluginConfig[event->TaskIndex][1] = g;   // G
            Settings.TaskDevicePluginConfig[event->TaskIndex][2] = b;   // B
            Candle_red = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
            Candle_green = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
            Candle_blue = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
            Settings.TaskDevicePluginConfig[event->TaskIndex][5] = 1;
            Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];   // ColorType (ColorSelected)

            String log = F("CAND : CMD - R ");
            log += r;
            log += F(" G ");
            log += g;
            log += F(" B ");
            log += b;
            addLog(LOG_LEVEL_DEBUG, log);
          } else {
            Settings.TaskDevicePluginConfig[event->TaskIndex][5] = 0;
            Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];   // ColorType (ColorDefault)
            addLog(LOG_LEVEL_DEBUG, F("CAND : CMD - Color : DEFAULT"));
          }

          //SaveTaskSettings(event->TaskIndex);
          //SaveSettings();

          success = true;
        }

        break;
      }

  }
  return success;
}

void SetPixelsBlack() {
  for (int i = 0; i < NUM_PIXEL; i++) {
    Candle_pixels->setPixelColor(i, Candle_pixels->Color(0, 0, 0));
  }
}

void SetPixelToColor(int PixelIdx) {
  Candle_pixels->setPixelColor(PixelIdx, Candle_pixels->Color(Candle_red, Candle_green, Candle_blue));
}

void type_Off() {
  SetPixelsBlack();
}

void type_Static_Light() {
  for (int i = 0; i < NUM_PIXEL; i++) {
    if (Candle_color == ColorDefault) {
      Candle_pixels->setPixelColor(i, 255, 255, 255);     // Default is white
    } else {
      Candle_pixels->setPixelColor(i, Candle_red, Candle_green, Candle_blue);
    }
  }
}

void type_Simple_Candle() {
  int r, g, b;
  if (Candle_color == ColorDefault) {
    r = 226, g = 042, b =  35;   // Regular (orange) flame
    //r = 158, g =   8, b = 148;   // Purple flame
    //r =  74, g = 150, b =  12;   // Green flame
  } else {
    r = Candle_red, g = Candle_green, b = Candle_blue;
  }

  //  Flicker, based on our initial RGB values
  for (int i = 0; i < NUM_PIXEL; i++) {
    int flicker = random(0, RANDOM_PIXEL);
    int r1 = r - flicker;
    int g1 = g - flicker;
    int b1 = b - flicker;
    if (g1 < 0) g1 = 0;
    if (r1 < 0) r1 = 0;
    if (b1 < 0) b1 = 0;
    Candle_pixels->setPixelColor(i, r1, g1, b1);
  }
}

void type_Advanced_Candle() {
  Candle_Temp[0] = random(1, 4); // 1..4  LEDs in RED
  Candle_Temp[1] = random(1, 4) + Candle_Temp[0]; // 1..3  LEDs in Yellow / Orange
  Candle_Temp[2] = random(0, 2); // 0..1  Choose Yellow = 0 / Orange = 1

  int colorbase[3];
  int color1[3];
  int color2[3];
  int color3[3];

  if (Candle_color == ColorDefault) {
    colorbase[0] = 255; colorbase[1] = 120; colorbase[2] = 0;   // Light Orange #FF7800
    color1[0] = 115; color1[1] = 50; color1[2] = 0;             // Brown      #733200
    color2[0] = 180; color2[1] = 80; color2[2] = 0;             // Orange     #B45000
    color3[0] =  70; color3[1] = 30; color3[2] = 0;              // Dark brown #4A2000
  } else {
    colorbase[0] = Candle_red; colorbase[1] = Candle_green; colorbase[2] = Candle_blue;
    double hsv[3];
    // Calc HSV
    RGBtoHSV(Candle_red, Candle_green, Candle_blue, hsv);
    double newH = hsv[0] - 5;
    if (newH < 0) { newH += 359; }
    double newV = hsv[2] / 2;
    double newV2 = hsv[2] / 4;
    // Calc new RGBs
    HSVtoRGB(newH, hsv[1], hsv[2], color1);
    HSVtoRGB(hsv[0], hsv[1], newV, color2);
    HSVtoRGB(newH, hsv[1], newV2, color3);
  }

  for (int j = 0; j < NUM_PIXEL/5; j++) {
    for (unsigned int i = 1; i < 6; i++){
      if (i <= Candle_Temp[0]) {
        Candle_pixels->setPixelColor(j * 5 + i - 1, colorbase[0], colorbase[1], colorbase[2]);
      }
      if (i > Candle_Temp[0] && i <= Candle_Temp[1]) {
        if (Candle_Temp[2] == 0){
          Candle_pixels->setPixelColor(j * 5 + i - 1, color1[0], color1[1], color1[2]);
        } else {
          Candle_pixels->setPixelColor(j * 5 + i - 1, color2[0], color2[1], color2[2]);
        }
      }
      if (i > Candle_Temp[1]) {
        Candle_pixels->setPixelColor(j * 5 + i - 1, color3[0], color3[1], color3[2]);
      }
    }
  }
}

void type_Police() {
  Candle_Temp[0]++;
  if (Candle_Temp[0] > NUM_PIXEL / 5) {
    Candle_Temp[0] = 0;
  }

  for (unsigned int i = 0; i < NUM_PIXEL / 5; i++) {
    if (i == Candle_Temp[0])
    {
      for (int j = 0; j < 5; j++) {
        if (Candle_color == ColorDefault) {
          Candle_pixels->setPixelColor(i * 5 + j, 0, 0, 255);
        } else {
          Candle_pixels->setPixelColor(i * 5 + j, Candle_red, Candle_green, Candle_blue);
        }
      }
    } else {
      for (int j = 0; j < 5; j++) {
        Candle_pixels->setPixelColor(i * 5 + j, 0, 0, 0);
      }
    }
  }
}

void type_BlinkStrobe() {
  Candle_Temp[0]++;
  if (Candle_Temp[0] > 1) {
    Candle_Temp[0] = 0;
  }

  for (int i = 0; i < NUM_PIXEL; i++) {
    if (Candle_Temp[0] == 0) {
      Candle_pixels->setPixelColor(i, 0, 0, 0);
    } else {
      if (Candle_color == ColorDefault) {
        Candle_pixels->setPixelColor(i, 255, 255, 255);     // Default is white
      } else {
        Candle_pixels->setPixelColor(i, Candle_red, Candle_green, Candle_blue);
      }
    }
  }
}

void type_ColorFader() {
  int colors[3];
  double hsv[3];
  if (Candle_color != ColorDefault) {
    if (Candle_Temp[0] > 254 && Candle_Temp[1] == 1) {
      Candle_Temp[1] = 0;
    }
    if (Candle_Temp[0] < 55 && Candle_Temp[1] == 0) {
      Candle_Temp[1] = 1;
    }

    if (Candle_Temp[1] > 0) {
      Candle_Temp[0]++;
    } else {
      Candle_Temp[0]--;
    }

    // Calc HSV
    // void RGBtoHSV(byte r, byte g, byte b, double hsv[3])
    RGBtoHSV(Candle_red, Candle_green, Candle_blue, hsv);

    // Calc RGB with new V
    // HSVtoRGB(int hue, int sat, int val, int colors[3])
    // hue: 0-359, sat: 0-255, val (lightness): 0-255
    HSVtoRGB(hsv[0], hsv[1], Candle_Temp[0], colors);

    for (int i = 0; i < NUM_PIXEL; i++) {
      Candle_pixels->setPixelColor(i, colors[0], colors[1], colors[2]);
    }
  } else {
    Candle_Temp[0]++;
    if (Candle_Temp[0] > 359) {
      Candle_Temp[0] = 0;
    }

    // hue: 0-359, sat: 0-255, val (lightness): 0-255
    HSVtoRGB(Candle_Temp[0], 255, 255, colors);

    for (int i = 0; i < NUM_PIXEL; i++) {
      Candle_pixels->setPixelColor(i, colors[0], colors[1], colors[2]);
    }
  }
}

// Effects additions
void type_Cylon(int EyeSize){
  byte red = 255; byte green = 255 ; byte blue = 255 ; // Default is white
  if (Candle_color != ColorDefault) {
    red = Candle_red; green = Candle_green ; blue = Candle_blue ;
  }

  if (Candle_Temp[0] >= NUM_PIXEL-EyeSize-1 ) { //max value
    Candle_Temp[1] = 0; //decrease
  } else if (Candle_Temp[0] <=0 ) { //min value
    Candle_Temp[1] = 1; //increase
  }
    if ( Candle_Temp[1] == 0 ) { // decrease
    Candle_Temp[1] = 0;
    Candle_Temp[0]--;
  } else { //increase
    Candle_Temp[1] = 1;
    Candle_Temp[0]++;
  }
  
  for(int i = 0; i < NUM_PIXEL-EyeSize-1; i++) {
    if (Candle_Temp[0]==i) {
      Candle_pixels->setPixelColor(i-1, 0, 0, 0);
      Candle_pixels->setPixelColor(i, red/10, green/10, blue/10);
      for(int j = 1; j <= EyeSize; j++) {
        Candle_pixels->setPixelColor(i+j, red, green, blue);
      }
      Candle_pixels->setPixelColor(i+EyeSize+1, red/10, green/10, blue/10);
      Candle_pixels->setPixelColor(i+EyeSize+2, 0, 0, 0);
    }
  }
}

void type_Sparkle() {
  byte red = 255; byte green = 255 ; byte blue = 255 ; // Default is white
  if (Candle_color != ColorDefault) {
    red = Candle_red; green = Candle_green ; blue = Candle_blue ;
  }
  int Pixel ;
  for (int i=0 ; i<10; i++)
  {
    Pixel = random(NUM_PIXEL);
    Candle_pixels->setPixelColor(Pixel,red,green,blue);
    Pixel = random(NUM_PIXEL);
    Candle_pixels->setPixelColor(Pixel,0,0,0);
  }
}


void type_Rainbow() {
  byte *c;
  uint16_t i;
  
  //for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
  Candle_Temp[0]++ ;
  if (Candle_Temp[0] > 256*5 ) Candle_Temp[0] = 0;
  
  for(i=0; i< NUM_PIXEL; i++) {
    c=Wheel(((i * 256 / NUM_PIXEL) + Candle_Temp[0]) & 255);
    Candle_pixels->setPixelColor(i, *c, *(c+1), *(c+2));
  }
}

byte * Wheel(byte WheelPos) {
  static byte c[3];
  if(WheelPos < 85) {
   c[0]=WheelPos * 3;
   c[1]=255 - WheelPos * 3;
   c[2]=0;
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   c[0]=255 - WheelPos * 3;
   c[1]=0;
   c[2]=WheelPos * 3;
  } else {
   WheelPos -= 170;
   c[0]=0;
   c[1]=WheelPos * 3;
   c[2]=255 - WheelPos * 3;
  }
  return c;
}


// Convert HSC Color to RGB Color
void HSVtoRGB(int hue, int sat, int val, int colors[3]) {
  // hue: 0-359, sat: 0-255, val (lightness): 0-255
  int r=0, g=0, b=0, base=0;

  if (sat == 0) { // Achromatic color (gray).
    colors[0]=val;
    colors[1]=val;
    colors[2]=val;
  }
  else  {
    base = ((255 - sat) * val)>>8;
    switch(hue/60) {
    case 0:
      r = val;
      g = (((val-base)*hue)/60)+base;
      b = base;
      break;
    case 1:
      r = (((val-base)*(60-(hue%60)))/60)+base;
      g = val;
      b = base;
      break;
    case 2:
      r = base;
      g = val;
      b = (((val-base)*(hue%60))/60)+base;
      break;
    case 3:
      r = base;
      g = (((val-base)*(60-(hue%60)))/60)+base;
      b = val;
      break;
    case 4:
      r = (((val-base)*(hue%60))/60)+base;
      g = base;
      b = val;
      break;
    case 5:
      r = val;
      g = base;
      b = (((val-base)*(60-(hue%60)))/60)+base;
      break;
    }
    colors[0]=r;
    colors[1]=g;
    colors[2]=b;
  }
}

// Convert RGB Color to HSV Color
void RGBtoHSV(byte r, byte g, byte b, double hsv[3]) {
    double rd = (double) r/255;
    double gd = (double) g/255;
    double bd = (double) b/255;
    double maxval = rd;
    if (gd > maxval) { maxval = gd; }
    if (bd > maxval) { maxval = bd; }
    double minval = rd;
    if (gd < minval) { minval = gd; }
    if (bd < minval) { minval = bd; }
    double h = 0, s, v = maxval;
    double d = maxval - minval;

    s = maxval == 0 ? 0 : d / maxval;

    if (maxval == minval) {
        h = 0; // achromatic
    } else {
        if (maxval == rd) {
            h = (gd - bd) / d + (gd < bd ? 6 : 0);
        } else if (maxval == gd) {
            h = (bd - rd) / d + 2;
        } else if (maxval == bd) {
            h = (rd - gd) / d + 4;
        }
        h /= 6;
    }

    hsv[0] = h * 360;
    hsv[1] = s * 255;
    hsv[2] = v * 255;
}
#endif // USES_P042

anthony420
New user
Posts: 4
Joined: 14 Oct 2017, 03:08

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#92 Post by anthony420 » 10 Oct 2018, 23:30

tozett wrote: 10 Oct 2018, 07:29 maybe an illustrating picture of your candles?

:D
I'm not so good at adding attachments, so hoping for the best. I have a video but can't seem to attach the .mov file type.
Attachments
IMG_1522.JPG
IMG_1522.JPG (936.58 KiB) Viewed 38306 times

TD-er
Core team member
Posts: 8607
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#93 Post by TD-er » 11 Oct 2018, 01:54

So you got it working now :)
I will have a look at your changes, since this plugin should be included in the current code base I guess.
See https://github.com/letscontrolit/ESPEas ... Candle.ino

I added an issue to merge the fixes: https://github.com/letscontrolit/ESPEasy/issues/1888

burton666
Normal user
Posts: 11
Joined: 02 Dec 2016, 19:52

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#94 Post by burton666 » 20 Oct 2018, 19:42

Is there any newbie guide of how to set up everything starting from a newly flashed wemos?

P406
New user
Posts: 9
Joined: 31 Dec 2018, 09:29

Re: Wifi Candle - illuminate with ESPEasy (WS2812)

#95 Post by P406 » 20 Mar 2019, 07:47

Unfortunately, moelski is not reading private messages, so I have to post it here... :?

Can anyone help me out to get a 24-LED-ring working?
I'm not very experienced in coding, so I don't know what to change and how to compile an "own" ESPeasy version.... :roll: :oops:
I'd read somewhere that there is a plugin version where you can "Switch" the number of pixels on the ESPeasy webpage, but couldn't find it....?!?

Any help would be appreciated, my wife is killing me cause our bed light lamp are dissassembled since weeks.... :?

Kind regards,

P406

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests