Copy philps Hue settings to other RGB device with Domoticz/Mysensor

Moderator: leecollings

Post Reply
franzelare
Posts: 141
Joined: Thursday 19 February 2015 21:48
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Copy philps Hue settings to other RGB device with Domoticz/Mysensor

Post by franzelare »

I have been annoyed by the high price of the HUE LED strips, we have a few HUE lamps at home and one led strip and would like more of the LED strips but not the retail price... The led strips are behind different cabinets in the living and we normally pick about the same color for them and we only set them once or twice a day, so I don't care about latency.

So my target was to make a cheap small copy of the HUE led strip with a wireless connection to domoticz that can copy over the colors of a HUE bulb or other LED strip.
Since I want it wireless mysensor seemed the most easy and since I already have a few other mysensor nodes.
To keep it wireless I decided to use a ESP unit and not a normal arduino with radio, just because of the size.

I made a small PCB with:
- 3 transistor's BC337 for PWM output to the led strip up to 0.8A per color (~10W/color)
- DB18B20 (to measure temperature and detect overheating)
- 3.3V power supply
- reset button
- header for programming
- jumper for GPIO 0 to set the unit to programming mode
Image
Image

I use a CP2102 programmer to program the ESP unit with arduino IDE
Image

and with a little 12V supply I can hook up any RGB LED strip
Image

I have made 2 arduino scripts to control the LED's, one based on the fastled library and one just writing analog output values for the PWM signal
Only open now is to fade in and out when changing brightness, but the start of that is already in the script
the temperature sensor will detect if the unit overheats and will switch if off for 1 minute, if that happens 5 times the unit will go into deep sleep mode and you need to manually reset the unit
The fast led version I also tested with adafruit neopixels... only the small strips with 8 lixed LEDs flicker but the normal LED strip not so that seems not related to my control but to the LED's

In the fast led based arduino code for brightness adjustment I just manually set a percentage that matches on first sight
Spoiler: show

Code: Select all

#define FASTLED_ESP8266_RAW_PIN_ORDER
#include <FastLED.h>

#include <EEPROM.h>
#include <SPI.h>
#include <DallasTemperature.h>
#include <OneWire.h>

// Enable debug prints to serial monitor
#define MY_DEBUG 

// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
#define MY_BAUD_RATE 9600

// Setup gateway
#define MY_GATEWAY_ESP8266
#define MY_ESP8266_SSID "MY WIFI"
#define MY_ESP8266_PASSWORD "password"
#define MY_IP_ADDRESS 192,168,2,151
#define MY_IP_GATEWAY_ADDRESS 192,168,2,254
#define MY_IP_SUBNET_ADDRESS 255,255,255,0
#define MY_PORT 5003      
#define MY_GATEWAY_MAX_CLIENTS 2
#define MY_MAC_ADDRESS 0x90, 0xA2, 0xDA, 0x10, 0x1D, 0x91

#include <ESP8266WiFi.h>
#include <MySensor.h>

#define SKETCH_NAME "RGB_STRIP_TEMPERATURE"
#define SKETCH_VERSION "1.0.0"
#define NODE_REPEAT false
#define NODE_ID 2

//setup timer to get temperature measurement
#include <SimpleTimer.h>
SimpleTimer timer;

//heartbeat timer
SimpleTimer timerheartbeat;
// define heartbeat variables
#define CHILD_ID_HEART 100
int heartbeatcount = 0;
MyMessage msgHeart(CHILD_ID_HEART,V_TRIPPED);

//RGB test sensor stuff
//define RGB pins
#define RED_PIN 12
#define GREEN_PIN 13
#define BLUE_PIN 14
int H=0;
int S=0;
int V=0;
int brightnessR = 0;
int brightnessG = 0;
int brightnessB = 0;
int brightnessRold = 0; //prepared for fading in and out of brightness
int brightnessGold = 0; //prepared for fading in and out of brightness
int brightnessBold = 0; //prepared for fading in and out of brightness
int Rcorrection = 100; // color correction for specific leds in %
int Gcorrection = 90; // color correction for specific leds in %
int Bcorrection = 100; // color correction for specific leds in %

#define CHILD_ID_RGB 0
#define ID_RGB_TEXT 38 //IDX of the text unility in domoticz holding the HEU values
int off = 0;        //intensity when off
int actRGBonoff=0;                        // OnOff flag
MyMessage msg(CHILD_ID_RGB,V_CUSTOM);

// Led brightness adjusement
const int pwmIntervals = 1023; //1023 for ESP units and 255 for arduino

// Dallas stuff
#define CHILD_ID_TEMP 1
#define ONE_WIRE_BUS 4 // Pin where dallase sensor is connected
#define MAX_ATTACHED_DS18B20 2
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
float lastTemperature[MAX_ATTACHED_DS18B20];
int numSensors=0;
boolean receivedConfig = false;
boolean metric = true;
// Initialize temperature message
MyMessage msgTemp(CHILD_ID_TEMP,V_TEMP);
float overheat=70;  //temperature at which the dimmer will shut off to prevent damage
#define CHILD_ID_OVERHEAT 200
MyMessage msgOverheat(CHILD_ID_OVERHEAT,V_TRIPPED);
int Overheatcounter = 0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting setup" );

  // Setup locally attached leds
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);

  sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
  present(CHILD_ID_RGB, S_RGB_LIGHT);
  present(CHILD_ID_TEMP, S_TEMP);
  request(CHILD_ID_RGB, V_RGB);
  present(CHILD_ID_OVERHEAT, S_DOOR);
//setup measurement timer interval
    timer.setInterval(60000, getTemp);  //  in miliseconds
// setup heartbeat timer interval
  timerheartbeat.setInterval(360000, checkReboot);  // 6 minutes in miliseconds
  present(CHILD_ID_HEART, S_DOOR);
// Startup up the OneWire library
  sensors.begin();
  // requestTemperatures() will not block current thread
  sensors.setWaitForConversion(false);
}

void presentation() {
  Serial.println("Presentation:");

  // Send the sketch version information to the gateway and Controller
  sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);

  // Fetch the number of attached temperature sensors 
  numSensors = sensors.getDeviceCount();
  Serial.print("temperature sensors: ");
  Serial.println(numSensors);

  // Present all sensors to controller
  for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
    present(CHILD_ID_TEMP, S_TEMP);
    }
  present(CHILD_ID_OVERHEAT, S_DOOR);
  present(CHILD_ID_RGB, S_RGB_LIGHT);
// Present heartbeat signal  
  present(CHILD_ID_HEART, S_DOOR);
// Presentation completed 
  Serial.println("Setup completed" );
}

//  Check if digital input has changed and send in new value
void loop() 
{
    timer.run();
    timerheartbeat.run();
} 


void checkReboot() {
  Serial.println("check if heart is still beating");
    if (heartbeatcount <= 4 ){
    send(msgHeart.set(0));
//    present(CHILD_ID, S_RGB_LIGHT);
//    request(CHILD_ID, V_RGB);
    send(msg.set(0));
    Serial.println("rebooting ESP due to no communication");
    ESP.restart();
  }
  else {
    heartbeatcount = 0;
    Serial.println("Heartbeat still beating");
    Serial.println("Heartbeat counter reset");
    Serial.print("Heartbeat count: ");
    Serial.println(heartbeatcount);
    send(msgHeart.set(0));
  }
}

void getTemp()     
{     
  Serial.println("Loop for temperature sensors:");
  // Fetch temperatures from Dallas sensors
  sensors.requestTemperatures();

  // query conversion time and sleep until conversion completed
  int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
  // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
  sleep(conversionTime);

  // Read temperatures and send them to controller
  for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
 
    // Fetch and round temperature to one decimal
    float temperature = static_cast<float>(static_cast<int>((getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;

    Serial.print("Reading sensor: ");
    Serial.print(i+1);
    Serial.print(" with value: ");
    Serial.println(temperature);
 
      // Send in the new temperature
      send(msgTemp.set(temperature,1));
      // Save new temperatures for next compare
      lastTemperature[i]=temperature;
      if (temperature>=overheat){
        Serial.println("Power off overheat protection" );
        send(msgOverheat.set(1));
        Overheatcounter = Overheatcounter +1;
        actRGBonoff=0;
        analogWrite(RED_PIN, off);
        analogWrite(GREEN_PIN, off);
        analogWrite(BLUE_PIN, off);
        send(msg.set(0));
        if (Overheatcounter == 5){
           ESP.deepSleep(999999999*999999999U, WAKE_NO_RFCAL);
        }
        Serial.println("Sleep 60 seconds to cool down" );
        delay(60000);
        Serial.println("Requestion RGB values" );
        send(msg.set(ID_RGB_TEXT));
      }

      if (temperature<=overheat){
              send(msgOverheat.set(0));
      }
    }
//    Serial.println("Rquest RGB settings");
//  present(CHILD_ID, S_RGB_LIGHT);
//  request(CHILD_ID, V_RGB);
  }


  
String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1  };
  int maxIndex = data.length()-1;
  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
      found++;
      strIndex[0] = strIndex[1]+1;
      strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }
  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

void showAnalogRGB( const CRGB& rgb)
{
//storing previous settings
    Serial.println("Storing previous settings");
      brightnessRold=brightnessR;
      brightnessGold=brightnessG;
      brightnessBold=brightnessB;
      
      Serial.print("rgb.r ");
      Serial.println(rgb.r);
      int brightnessR=(((rgb.r*pwmIntervals)/255)*Rcorrection)/100;
      Serial.print("brightnessR ");
      Serial.println(brightnessR);
  analogWrite(RED_PIN,   brightnessR );

      Serial.print("rgb.g ");
      Serial.println(rgb.g);
      int brightnessG=(((rgb.g*pwmIntervals)/255)*Gcorrection)/100;
      Serial.print("brightnessG ");
      Serial.println(brightnessG);
  analogWrite(GREEN_PIN, brightnessG );

      Serial.print("rgb.b ");
      Serial.println(rgb.b);
      int brightnessB=(((rgb.b*pwmIntervals)/255)*Bcorrection)/100;
      Serial.print("brightnessB ");
      Serial.println(brightnessB);
  analogWrite(BLUE_PIN,  brightnessB );
}

void receive(const MyMessage &message) {

  //check if the message is heartbeat
  if (message.type==V_LIGHT){
    if (message.sensor==CHILD_ID_HEART) {
     // Read message
     Serial.print("Incoming change for sensor:");
     Serial.print(message.sensor);
     Serial.print(", New status: ");
     Serial.println(message.getBool());
        send(msgHeart.set(0));
        heartbeatcount = heartbeatcount+1;
        Serial.print("Heartbeat count: ");
        Serial.println(heartbeatcount);
     } 
  }
  if (message.type == V_RGB || message.type == V_DIMMER) {
    if (actRGBonoff == 1){
    Serial.println("RGB message received" );
    Serial.println("Sleep before requesting RGB values" );
    sleep (2000);
    Serial.println("Requesting RGB values" );
    send(msg.set(ID_RGB_TEXT));
    }
  }
  if (message.type == V_CUSTOM) {
   if (actRGBonoff == 1){
    String cMessage =  message.getString();
    Serial.print("cMessage" );
    Serial.println(cMessage);
    int Horg;
    int H;
    static uint8_t S;
    static uint8_t V; 
    Horg=getValue(cMessage, '#', 2).toInt();
    H=((Horg*255)/65536);
    S=getValue(cMessage, '#', 3).toInt();
    V=getValue(cMessage, '#', 4).toInt();
    showAnalogRGB( CHSV( H, S, V) );

    Serial.print("Horg ");
    Serial.println(Horg);
    Serial.print("H ");
    Serial.println(H);
    Serial.print("S ");
    Serial.println(S);
    Serial.print("V ");
    Serial.println(V);
  }
}
  

  if (message.type == V_LIGHT and message.sensor== CHILD_ID_RGB) {
   if (message.getInt() == 0) {
      Serial.println("Power off toggle" );
      analogWrite(RED_PIN, off);
      analogWrite(GREEN_PIN, off);
      analogWrite(BLUE_PIN, off);

      actRGBonoff=0;
    }
    if (message.getInt() == 1) {
      Serial.println("Power on toggle" );
      Serial.println("Sleep before requesting RGB values" );
      actRGBonoff=1;
      sleep (2000);
      Serial.println("Requesting RGB values" );
      send(msg.set(ID_RGB_TEXT));
    }
  }
      Serial.println(" ");
}

analog output write code i used a brightness adjustment trick found on this page
https://diarmuid.ie/blog/pwm-exponentia ... platforms/
Spoiler: show

Code: Select all

#include <EEPROM.h>
#include <SPI.h>
#include <DallasTemperature.h>
#include <OneWire.h>

// Enable debug prints to serial monitor
#define MY_DEBUG 

// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
#define MY_BAUD_RATE 9600

// Setup gateway
#define MY_GATEWAY_ESP8266
#define MY_ESP8266_SSID "MY WIFI"
#define MY_ESP8266_PASSWORD "password"
#define MY_IP_ADDRESS 192,168,2,151
#define MY_IP_GATEWAY_ADDRESS 192,168,2,254
#define MY_IP_SUBNET_ADDRESS 255,255,255,0
#define MY_PORT 5003      
#define MY_GATEWAY_MAX_CLIENTS 2
#define MY_MAC_ADDRESS 0x90, 0xA2, 0xDA, 0x10, 0x1D, 0x91

#include <ESP8266WiFi.h>
#include <MySensor.h>

#define SKETCH_NAME "RGB_STRIP_TEMPERATURE"
#define SKETCH_VERSION "1.0.0"
#define NODE_REPEAT false
#define NODE_ID 2

//setup timer to get temperature measurement
#include <SimpleTimer.h>
SimpleTimer timer;

//heartbeat timer
SimpleTimer timerheartbeat;
// define heartbeat variables
#define CHILD_ID_HEART 100
int heartbeatcount = 0;
MyMessage msgHeart(CHILD_ID_HEART,V_TRIPPED);

//RGB test sensor stuff
//define RGB pins
#define RED_PIN 12
#define GREEN_PIN 13
#define BLUE_PIN 14
int brightnessR;
int brightnessG;
int brightnessB;
int brightnessRold = 0; //prepared for fading in and out of brightness
int brightnessGold = 0; //prepared for fading in and out of brightness
int brightnessBold = 0; //prepared for fading in and out of brightness
int Rcorrection = 100; // color correction for specific leds in %
int Gcorrection = 100; // color correction for specific leds in %
int Bcorrection = 100; // color correction for specific leds in %

#define CHILD_ID_RGB 0
#define ID_RGB_TEXT 38 //IDX of the text unility in domoticz holding the HEU values
long RGB_values[3] = {0, 0, 0};
int off = 0;        //intensity when off
String hexstring;   //HEX string for RGB value
int dimmer;       //dimmer value in percentage
int actRGBonoff=0;                        // OnOff flag
MyMessage msg(CHILD_ID_RGB,V_CUSTOM);

// Led brightness adjusement
// The number of Steps between the output being on and off
// source from https://diarmuid.ie/blog/pwm-exponential-led-fading-on-arduino-or-other-platforms/
const int pwmIntervals = 1023;
const int brightnessmax = 1023;
// The R value in the graph equation
float R;

// Dallas stuff
#define CHILD_ID_TEMP 1
#define ONE_WIRE_BUS 4 // Pin where dallase sensor is connected
#define MAX_ATTACHED_DS18B20 2
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature.
float lastTemperature[MAX_ATTACHED_DS18B20];
int numSensors=0;
boolean receivedConfig = false;
boolean metric = true;
// Initialize temperature message
MyMessage msgTemp(CHILD_ID_TEMP,V_TEMP);
float overheat=70;  //temperature at which the dimmer will shut off to prevent damage
#define CHILD_ID_OVERHEAT 200
MyMessage msgOverheat(CHILD_ID_OVERHEAT,V_TRIPPED);
int Overheatcounter = 0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting setup" );

  // Setup locally attached leds
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);

  sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
  present(CHILD_ID_RGB, S_RGB_LIGHT);
  present(CHILD_ID_TEMP, S_TEMP);
  request(CHILD_ID_RGB, V_RGB);
  present(CHILD_ID_OVERHEAT, S_DOOR);
// calculatebrightness adjustment
  R = (pwmIntervals * log10(2))/(log10(brightnessmax));
//setup measurement timer interval
    timer.setInterval(60000, getTemp);  //  in miliseconds
// setup heartbeat timer interval
  timerheartbeat.setInterval(360000, checkReboot);  // 6 minutes in miliseconds
  present(CHILD_ID_HEART, S_DOOR);
// Startup up the OneWire library
  sensors.begin();
  // requestTemperatures() will not block current thread
  sensors.setWaitForConversion(false);
}

void presentation() {
  Serial.println("Presentation:");

  // Send the sketch version information to the gateway and Controller
  sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);

  // Fetch the number of attached temperature sensors 
  numSensors = sensors.getDeviceCount();
  Serial.print("sensors: ");
  Serial.println(numSensors);

  // Present all sensors to controller
  for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
    present(CHILD_ID_TEMP, S_TEMP);
    }
  present(CHILD_ID_OVERHEAT, S_DOOR);
  present(CHILD_ID_RGB, S_RGB_LIGHT);
// Present heartbeat signal  
  Serial.println("Present heartbeat signal");
  present(CHILD_ID_HEART, S_DOOR);
// Presentation completed 
  Serial.println("Setup completed" );
}

//  Check if digital input has changed and send in new value
void loop() 
{
    timer.run();
    timerheartbeat.run();
} 


void checkReboot() {
  Serial.println("check if heart is still beating");
    if (heartbeatcount <= 4 ){
    send(msgHeart.set(0));
//    present(CHILD_ID, S_RGB_LIGHT);
//    request(CHILD_ID, V_RGB);
    send(msg.set(0));
    Serial.println("rebooting ESP due to no communication");
    ESP.restart();
  }
  else {
    heartbeatcount = 0;
    Serial.println("Heartbeat still beating");
    Serial.println("Heartbeat counter reset");
    Serial.print("Heartbeat count: ");
    Serial.println(heartbeatcount);
    send(msgHeart.set(0));
  }
}

void getTemp()     
{     
  Serial.println("Loop for temperature sensors:");
  // Fetch temperatures from Dallas sensors
  sensors.requestTemperatures();

  // query conversion time and sleep until conversion completed
  int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
  // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
  sleep(conversionTime);

  // Read temperatures and send them to controller
  for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
 
    // Fetch and round temperature to one decimal
    float temperature = static_cast<float>(static_cast<int>((getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;

    Serial.print("Reading sensor: ");
    Serial.print(i+1);
    Serial.print(" with value: ");
    Serial.println(temperature);
 
      // Send in the new temperature
      send(msgTemp.set(temperature,1));
      // Save new temperatures for next compare
      lastTemperature[i]=temperature;
      if (temperature>=overheat){
        Serial.println("Power off overheat protection" );
        send(msgOverheat.set(1));
        Overheatcounter = Overheatcounter +1;
        actRGBonoff=0;
        analogWrite(RED_PIN, off);
        analogWrite(GREEN_PIN, off);
        analogWrite(BLUE_PIN, off);
        send(msg.set(0));
        if (Overheatcounter == 5){
           ESP.deepSleep(999999999*999999999U, WAKE_NO_RFCAL);
        }
        Serial.println("Sleep 60 seconds to cool down" );
        delay(60000);
        Serial.println("Requestion RGB values" );
        send(msg.set(ID_RGB_TEXT));
      }
      if (temperature<=overheat){
         send(msgOverheat.set(0));
      }
    }
//    Serial.println("Rquest RGB settings");
//  present(CHILD_ID, S_RGB_LIGHT);
//  request(CHILD_ID, V_RGB);
  }


  
String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1  };
  int maxIndex = data.length()-1;
  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
      found++;
      strIndex[0] = strIndex[1]+1;
      strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }
  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

void receive(const MyMessage &message) {

  //check if the message is heartbeat
  if (message.type==V_LIGHT){
    if (message.sensor==CHILD_ID_HEART) {
     // Read message
     Serial.print("Incoming change for sensor:");
     Serial.print(message.sensor);
     Serial.print(", New status: ");
     Serial.println(message.getBool());
        send(msgHeart.set(0));
        heartbeatcount = heartbeatcount+1;
        Serial.print("Heartbeat count: ");
        Serial.println(heartbeatcount);
     } 
  }
  if (message.type == V_RGB || message.type == V_DIMMER) {
    if (actRGBonoff == 1){
    Serial.println("RGB message received" );
    Serial.println("Sleep before requesting RGB values" );
    sleep (2000);
    Serial.println("Requesting RGB values" );
    send(msg.set(ID_RGB_TEXT));
    }
  }
  if (message.type == V_CUSTOM) {
//storing previous settings
    Serial.println("Storing previous settings");
      brightnessRold=brightnessR;
      brightnessGold=brightnessG;
      brightnessBold=brightnessB;
   
   if (actRGBonoff == 1){
    String cMessage =  message.getString();
    Serial.print("cMessage" );
    Serial.println(cMessage);
    hexstring=getValue(cMessage, '#', 2);
// split dimmer values
    dimmer=(getValue(cMessage, '#', 3)).toInt();
    Serial.print("Dimmer " );
    Serial.println(dimmer);
// split RGB values
    Serial.print("New RGB values " );
    Serial.println(hexstring);
    long number = (long) strtol( &hexstring[0], NULL, 16);
    Serial.println(number);
// separate HEX string in RGB values
    RGB_values[0] = number >> 16;
    RGB_values[1] = number >> 8 & 0xFF;
    RGB_values[2] = number & 0xFF;

// RGB value to display as send by the server
    long r1 = int(RGB_values[0]);
    long g1 = int(RGB_values[1]);
    long b1 = int(RGB_values[2]);

// calculate RGB value to display
    long r = int((RGB_values[0] * dimmer/100));
    long g = int((RGB_values[1] * dimmer/100));
    long b = int((RGB_values[2] * dimmer/100));

// set value of RGB controller
    int red = ((r*1023)/255);
    int green = ((g*1023)/255);
    int blue = ((b*1023)/255);

//adjust brightness non linear
    brightnessR = pow (2, (red / R)) - 1;
    brightnessG = pow (2, (green / R)) - 1;
    brightnessB = pow (2, (blue / R)) - 1;

int Rpwm=(brightnessR*Rcorrection)/100;
int Gpwm=(brightnessG*Gcorrection)/100;
int Bpwm=(brightnessB*Bcorrection)/100;

    Serial.print("r ");
    Serial.println(r1);
    Serial.print("r dimmed ");
    Serial.println(r);
    Serial.print("r-ESP ");
    Serial.println(red);
    
    Serial.print("g ");
    Serial.println(g1);
    Serial.print("g dimmed ");
    Serial.println(g);
    Serial.print("g-ESP ");
    Serial.println(green);

    Serial.print("b ");
    Serial.println(b1);
    Serial.print("b dimmed ");
    Serial.println(b);
    Serial.print("b-ESP ");
    Serial.println(blue);

    Serial.print("red brightness adjusted ");
    Serial.println(brightnessR);
    Serial.print("green brightness adjusted ");
    Serial.println(brightnessG);
    Serial.print("blue brightness adjusted ");
    Serial.println(brightnessB);
    
    Serial.print("red PWM output ");
    Serial.println(Rpwm);
    Serial.print("green PWM output ");
    Serial.println(Gpwm);
    Serial.print("blue PWM output ");
    Serial.println(Bpwm);

// write RGB value to controller
 analogWrite(RED_PIN, Rpwm);
 analogWrite(GREEN_PIN, Gpwm);
 analogWrite(BLUE_PIN, Bpwm);

  
  }
}
  

  if (message.type == V_LIGHT and message.sensor== CHILD_ID_RGB) {
   if (message.getInt() == 0) {
      Serial.println("Power off toggle" );
      analogWrite(RED_PIN, off);
      analogWrite(GREEN_PIN, off);
      analogWrite(BLUE_PIN, off);
      brightnessRold=0;
      brightnessGold=0;
      brightnessBold=0;
      actRGBonoff=0;
    }
    if (message.getInt() == 1) {
      Serial.println("Power on toggle" );
      Serial.println("Sleep before requesting RGB values" );
      actRGBonoff=1;
      sleep (2000);
      Serial.println("Requesting RGB values" );
      send(msg.set(ID_RGB_TEXT));
    }
  }
      Serial.println(" ");
  
}
in domoticz I have 2 lua scripts running for the HUE control, 1 time based and one triggered by the device change
next to that I have 1 watchdog script that switches on ID 100 to the node and the node will reply with an off at that ID so the node can be reset if there is no communication
a user variable has to be creased to store the current HUE settings (String)
a dummy text utility has to be created to store the HSV or RGB and dimmer values for the mysensor node to request

The device script contains calculations from HSV to RGB and RGB hex, I tried different formats for fowarding the data to the mysensor node and just kept it in the script in case I might need it later for troubleshooting
Spoiler: show

Code: Select all

-- this script reads the setting of 1 HUE RGB device and forwards this to a mysensor RGB dimmer
-- one script will do this time based and the second script will do this on a device change, in order to capture changed made from domoticz and through the HUE bridge directly
-- HUE stores the values in HSV format where the mysensor node uses RGB values for the RGB LED's so these have to be converted before forwarding

-- a user variable has to be creased to store the current HUE settings (String)
-- a dummy text utility has to be created to store the HSV or RGB and dimmer values for the mysensor node to request

-- additional libraries for lua have to be installed
-- how to do this can be found in the help wiki http://www.domoticz.com/wiki/Upload_energy_data_to_PVoutput#Install_socket_library
-- or from  http://www.domoticz.com/forum/viewtopic.php?f=5&t=1847&p=22638#p22638
-- for json processing I use http://regex.info/code/JSON.lua on a raspberry pi
-- on a synology nas dkjson seems to do a better job http://dkolf.de/src/dkjson-lua.fsl/home
-- all need to end up in /usr/local/lib/lua/5.2

commandArray =  {}

-- fixed values
base_url = 'http://192.168.2.150/api/fd81c2245c8797cec333e351d01a3' 	-- hue URL and username
domoticz_url = 'http://192.168.2.140:8080' 				--URL of domoticz server
HUE_Strip_ID = 6 							        -- HUE ID of deviced to be replicated
HUE_CURRENT = 'Led_HUE'                             -- Uservariable (String) to store HUE setting
Source_Name = 'HueStrip'                            -- Name of the HUE device to be copied in Domoticz
Target_IDX = 229    	    						-- IDX of target device
Target_Name = 'RGB_Led'    	    					-- exact device name
Target_IDX_TXT=38                                   -- IDX for HSV values
ForwardType = 'HSV'                                  -- HSV or RGB to be forwarded to the mysensor node

PRINT_MODE = false		-- when true wil print output to log and send notifications

if (devicechanged[Source_Name]) then -- optional and (uservariables['HUE_Forward_LAN']==1)
	if (otherdevices[Source_Name] == 'Off') then
		-- set copied device to off
		commandArray[Target_Name] = 'Off'
	else

-- Only load libaries now
http = require('socket.http')
ltn12 = require('ltn12')
json = require('JSON')
io = require('io')

-- set some local variables
device = ''
mode = 'GET'
params = ''
 
function hueread(device, operation, mode)
         local t = {}
         local url = base_url .. device
         local req_body = operation
	if PRINT_MODE == true then
        	 print(url)
	         print(req_body)
	end
         local headers = {
            ["Content-Type"] = "application/json";
            ["Content-Length"] = #req_body;
          }
          client, code, headers, status = http.request{url=url, headers=headers, source=ltn12.source.string(req_body), sink = ltn12.sink.table(t), method=mode}
	if PRINT_MODE == true then
        	 print(status)
	end
 return t
end


 
function processJSON(t)
	obj, pos, err = json:decode(table.concat(t),1,nil)
	  if PRINT_MODE == true then
        print(table.concat(t))
	    print("check for error")
	  end
	if err then
        print ("Error for HUE Bridge:", err)
    else
		if PRINT_MODE == true then
        		print("no error")
		end
        data = ''
	    i=HUE_Strip_ID
        state=obj.lights[tostring(i)].state
	    dataHUE = data .. state.bri ..'|'.. state.hue ..'|'.. state.sat
    	dataStatus = state.on
-- checking if HUE strip is off
	if state.on==false then
		if PRINT_MODE == true then
			if otherdevices[Target_Name] ~= 'Off' then
				print('HUE LED is off, but RGB LED was on')
				else	
				print('HUE LED is off, no action')
			end
	    commandArray[Target_Name] = 'Off'	
		    if PRINT_MODE == true then
			    print('Sending off switch command just to be sure')
		    end
		end
	else	
-- checking if HUE strip is on but led strip is off
	if state.on==true then
		if otherdevices[Target_Name] == 'Off' then
			if PRINT_MODE == true then
				print('Switching RGB led on')
			end
		commandArray[Target_Name] = 'On'	
			if PRINT_MODE == true then
				print('Hue ID checked: ' .. i)
				print('Status on: On')
				print('HUE: ' .. dataHUE)        
			    print('length of encode '..#dataHUE)
			end
		else
			if PRINT_MODE == true then
				print('RGB led already on, checking settings')
			end
			commandArray[Target_Name] = 'On'	
			if PRINT_MODE == true then
				print('Sending on switch command just to be sure')
			end
		end
-- Collecting color data to compare
	Old_data = tostring(uservariables[HUE_CURRENT])
	New_data = tostring(dataHUE)

    if New_data ~= Old_data then
	    print('HUE data changed')
    	if PRINT_MODE == true then
	    	print('New data:' .. New_data)
		    print('Old data:' ..Old_data)
		    print('')
	    end
    -- convert HUE values to HSV
    	H=((state.hue)/65534)
	    S=((state.sat)/254)
    	V=((state.bri)/254)
    --convert HUE to domoticz values
    	Hue=tostring(math.floor(H*360))
	    Sat=tostring(math.floor(S*100))
	    Bri=tostring(math.floor(V*100))
    -- convert HSV to RGB and RGB hex values
    	R, G, B =HSVtoRGB(H, S, V) 
        
    	if R >= 16 then
	    	Rhex=num2hex(R)
    	else
	    	Rhex='0'.. num2hex(R)
	    end
	    if G >= 16 then
    		Ghex=num2hex(G)
	    else
		    Ghex='0'.. num2hex(G)
    	end
	    if B >= 16 then
		    Bhex=num2hex(B)
    	else
	    	Bhex='0'.. num2hex(B)
	    end
    	RGB= R ..'|'.. G ..'|'.. B
	    RGBhex= Rhex ..''.. Ghex ..''.. Bhex
        if PRINT_MODE == true then
    -- Reverse calculations of hue values for validation
	        Hr, Sr, Vr =RGBtoHSV(R, G, B)
		    Hrev=round((Hr*65536),0)
    		Srev=round((Sr*256),0)
	    	Vrev=round((Vr*256),0)

        -- print all calculated data
    	    print('Hue Hue light: ' .. state.hue)
    	    print('Sat Hue light: ' .. state.sat)
        	print('Bright Hue light: ' .. state.bri)
	        print(' ')
        	print('Hue domoticz: ' .. Hue)
	        print('Sat domoticz: ' .. Sat)
    	    print('Bri domoticz: ' .. Bri)
    	    print(' ')
        	print('H: ' .. H)
    	    print('S: ' .. S)
        	print('V: ' .. V)
	        print(' ')
        	print('R: ' .. R)
	        print('G: ' .. G)
    	    print('B: ' .. B)
    	    print('RGB: ' .. RGB)
        	print(' ')
	        print('Rhex: ' .. Rhex)
        	print('Ghex: ' .. Ghex)
	        print('Bhex: ' .. Bhex)
    	    print('RGBhex: ' .. RGBhex)
    	    print(' ')
        	print('H reversed: ' .. Hrev)
	        print('S reversed: ' .. Srev)
    	    print('V reversed: ' .. Vrev)
        end

    -- set LED strip
        if (ForwardType=='RGB') then
	    -- store RGB as text
    		datanew_TXT=RGBhex..";"..Bri..";"
	        commandArray['UpdateDevice'] = Target_IDX_TXT .. '|0|' .. tostring(datanew_TXT)
	        if PRINT_MODE == true then
    		    print('Storing RGB text value:' .. datanew_TXT)
	    	end
        end
        if (ForwardType=='HSV') then    
	    -- store HSV as text
		    datanew_HSV=state.hue..";"..state.sat..";"..state.bri..";"
    	    commandArray['UpdateDevice'] = Target_IDX_TXT .. '|0|' .. tostring(datanew_HSV)
	        if PRINT_MODE == true then
		        print('Storing HSV text value:' .. datanew_HSV)
    		end
        end
    	--send HUE values to domoticz
            urlRGBLED = 'http://127.0.0.1:8080/json.htm?type=command&param=setcolbrightnessvalue&idx=' .. Target_IDX .. '&hue=' ..Hue.. '&brightness=' ..Bri..'&saturation=' ..Sat.. '&iswhite=false'
            commandArray['OpenURL']= urlRGBLED

    	-- store new HUE values in variables
	    	commandArray['Variable:Led_HUE'] = New_data

    else
	    print('No change in HUE values')
    end


	end
   end
  end
 return
end



function HSVtoRGB(h, s, v)
  local r, g, b

  local i = math.floor(h * 6);
  local f = h * 6 - i;
  local p = v * (1 - s);
  local q = v * (1 - f * s);
  local t = v * (1 - (1 - f) * s);

  i = i % 6

  if i == 0 then r, g, b = v, t, p
  end
  if i == 1 then r, g, b = q, v, p
  end
  if i == 2 then r, g, b = p, v, t
  end
  if i == 3 then r, g, b = p, q, v
  end
  if i == 4 then r, g, b = t, p, v
  end
  if i == 5 then r, g, b = v, p, q
  end

	R=round((r*255),0)
	G=round((g*255),0)
	B=round((b*255),0)
  return R, G, B
end




function RGBtoHSV(r, g, b)
  r, g, b = r / 255, g / 255, b / 255
  local max, min = math.max(r, g, b), math.min(r, g, b)
  local h, s, v
  v = max

  local d = max - min
  if max == 0 then s = 0 else s = d / max end

  if max == min then
    h = 0 -- achromatic
  else
    if max == r then
    h = (g - b) / d
    if g < b then h = h + 6 end
    elseif max == g then h = (b - r) / d + 2
    elseif max == b then h = (r - g) / d + 4
    end
    h = h / 6
  end

  return h, s, v
end

function round(num, idp)
  local mult = 10^(idp or 0)
  return math.floor(num * mult + 0.5) / mult
end

function num2hex(num)
    local hexstr = '0123456789ABCDEF'
    local s = ''
    while num > 0 do
        local mod = math.fmod(num, 16)
        s = string.sub(hexstr, mod+1, mod+1) .. s
        num = math.floor(num / 16)
    end
    if s == '' then s = '0' end
    return s
end

t = hueread(device, params, mode)
processJSON(t)
end
end
return commandArray
The time based script
Spoiler: show

Code: Select all

-- this script reads the setting of 1 HUE RGB device and forwards this to a mysensor RGB dimmer
-- one script will do this time based and the second script will do this on a device change, in order to capture changed made from domoticz and through the HUE bridge directly
-- HUE stores the values in HSV format where the mysensor node uses RGB values for the RGB LED's so these have to be converted before forwarding

-- a user variable has to be creased to store the current HUE settings (String)
-- a dummy text utility has to be created to store the HSV or RGB and dimmer values for the mysensor node to request

-- additional libraries for lua have to be installed
-- how to do this can be found in the help wiki http://www.domoticz.com/wiki/Upload_energy_data_to_PVoutput#Install_socket_library
-- or from  http://www.domoticz.com/forum/viewtopic.php?f=5&t=1847&p=22638#p22638
-- for json processing I use http://regex.info/code/JSON.lua on a raspberry pi
-- on a synology nas dkjson seems to do a better job http://dkolf.de/src/dkjson-lua.fsl/home
-- all need to end up in /usr/local/lib/lua/5.2

commandArray =  {}

-- fixed values
base_url = 'http://192.168.2.150/api/fd81c2245c8797cec333e351d01a3' 	-- hue URL and username
domoticz_url = 'http://192.168.2.140:8080' 			--URL of domoticz server
HUE_Strip_ID = 6 							        -- HUE ID of deviced to be replicated
HUE_CURRENT = 'Led_HUE'                             -- uservariable (String) to store HUE setting
Source_Name = 'HueStrip'                            -- Name of the HUE device to be copied in Domoticz
Target_IDX = 229    	    						-- IDX of target device
Target_Name = 'RGB_Led'    	    					-- exact device name
Target_IDX_TXT=38                                   -- IDX for HSV values
ForwardType = 'HSV'                                 -- HSV or RGB to be forwarded to the mysensor node

PRINT_MODE = false		-- when true wil print output to log and send notifications

-- Only load libaries now
http = require('socket.http')
ltn12 = require('ltn12')
json = require('JSON')
io = require('io')

-- set some local variables
device = ''
mode = 'GET'
params = ''
 
function hueread(device, operation, mode)
         local t = {}
         local url = base_url .. device
         local req_body = operation
	if PRINT_MODE == true then
        	 print(url)
	         print(req_body)
	end
         local headers = {
            ["Content-Type"] = "application/json";
            ["Content-Length"] = #req_body;
          }
          client, code, headers, status = http.request{url=url, headers=headers, source=ltn12.source.string(req_body), sink = ltn12.sink.table(t), method=mode}
	if PRINT_MODE == true then
        	 print(status)
	end
 return t
end


 
function processJSON(t)
	obj, pos, err = json:decode(table.concat(t),1,nil)
	  if PRINT_MODE == true then
        print(table.concat(t))
	    print("check for error")
	  end
	if err then
        print ("Error for HUE Bridge:", err)
    else
		if PRINT_MODE == true then
        		print("no error")
		end
        data = ''
	    i=HUE_Strip_ID
        state=obj.lights[tostring(i)].state
	    dataHUE = data .. state.bri ..'|'.. state.hue ..'|'.. state.sat
    	dataStatus = state.on
-- checking if HUE strip is off
	if state.on==false then
		if PRINT_MODE == true then
			if otherdevices[Target_Name] ~= 'Off' then
				print('HUE LED is off, but RGB LED was on')
				else	
				print('HUE LED is off, no action')
			end
	    commandArray[Target_Name] = 'Off'	
		    if PRINT_MODE == true then
			    print('Sending off switch command just to be sure')
		    end
		end
	else	
-- checking if HUE strip is on but led strip is off
	if state.on==true then
		if otherdevices[Target_Name] == 'Off' then
			if PRINT_MODE == true then
				print('Switching RGB led on')
			end
		commandArray[Target_Name] = 'On'	
			if PRINT_MODE == true then
				print('Hue ID checked: ' .. i)
				print('Status on: On')
				print('HUE: ' .. dataHUE)        
			    print('length of encode '..#dataHUE)
			end
		else
			if PRINT_MODE == true then
				print('RGB led already on, checking settings')
			end
			commandArray[Target_Name] = 'On'	
			if PRINT_MODE == true then
				print('Sending on switch command just to be sure')
			end
		end
-- Collecting color data to compare
	Old_data = tostring(uservariables[HUE_CURRENT])
	New_data = tostring(dataHUE)

    if New_data ~= Old_data then
	    print('HUE data changed')
    	if PRINT_MODE == true then
	    	print('New data:' .. New_data)
		    print('Old data:' ..Old_data)
		    print('')
	    end
    -- convert HUE values to HSV
    	H=((state.hue)/65534)
	    S=((state.sat)/254)
    	V=((state.bri)/254)
    --convert HUE to domoticz values
    	Hue=tostring(math.floor(H*360))
	    Sat=tostring(math.floor(S*100))
	    Bri=tostring(math.floor(V*100))
    -- convert HSV to RGB and RGB hex values
    	R, G, B =HSVtoRGB(H, S, V) 
        
    	if R >= 16 then
	    	Rhex=num2hex(R)
    	else
	    	Rhex='0'.. num2hex(R)
	    end
	    if G >= 16 then
    		Ghex=num2hex(G)
	    else
		    Ghex='0'.. num2hex(G)
    	end
	    if B >= 16 then
		    Bhex=num2hex(B)
    	else
	    	Bhex='0'.. num2hex(B)
	    end
    	RGB= R ..'|'.. G ..'|'.. B
	    RGBhex= Rhex ..''.. Ghex ..''.. Bhex
        if PRINT_MODE == true then
    -- Reverse calculations of hue values for validation
	        Hr, Sr, Vr =RGBtoHSV(R, G, B)
		    Hrev=round((Hr*65536),0)
    		Srev=round((Sr*256),0)
	    	Vrev=round((Vr*256),0)

        -- print all calculated data
    	    print('Hue Hue light: ' .. state.hue)
    	    print('Sat Hue light: ' .. state.sat)
        	print('Bright Hue light: ' .. state.bri)
	        print(' ')
        	print('Hue domoticz: ' .. Hue)
	        print('Sat domoticz: ' .. Sat)
    	    print('Bri domoticz: ' .. Bri)
    	    print(' ')
        	print('H: ' .. H)
    	    print('S: ' .. S)
        	print('V: ' .. V)
	        print(' ')
        	print('R: ' .. R)
	        print('G: ' .. G)
    	    print('B: ' .. B)
    	    print('RGB: ' .. RGB)
        	print(' ')
	        print('Rhex: ' .. Rhex)
        	print('Ghex: ' .. Ghex)
	        print('Bhex: ' .. Bhex)
    	    print('RGBhex: ' .. RGBhex)
    	    print(' ')
        	print('H reversed: ' .. Hrev)
	        print('S reversed: ' .. Srev)
    	    print('V reversed: ' .. Vrev)
        end

    -- set LED strip
        if (ForwardType=='RGB') then
	    -- store RGB as text
    		datanew_TXT=RGBhex..";"..Bri..";"
	        commandArray['UpdateDevice'] = Target_IDX_TXT .. '|0|' .. tostring(datanew_TXT)
	        if PRINT_MODE == true then
    		    print('Storing RGB text value:' .. datanew_TXT)
	    	end
        end
        if (ForwardType=='HSV') then    
	    -- store HSV as text
		    datanew_HSV=state.hue..";"..state.sat..";"..state.bri..";"
    	    commandArray['UpdateDevice'] = Target_IDX_TXT .. '|0|' .. tostring(datanew_HSV)
	        if PRINT_MODE == true then
		        print('Storing HSV text value:' .. datanew_HSV)
    		end
        end
    	--send HUE values to domoticz
            urlRGBLED = 'http://127.0.0.1:8080/json.htm?type=command&param=setcolbrightnessvalue&idx=' .. Target_IDX .. '&hue=' ..Hue.. '&brightness=' ..Bri..'&saturation=' ..Sat.. '&iswhite=false'
            commandArray['OpenURL']= urlRGBLED

    	-- store new HUE values in variables
	    	commandArray['Variable:Led_HUE'] = New_data

    else
	    print('No change in HUE values')
    end


	end
   end
  end
 return
end



function HSVtoRGB(h, s, v)
  local r, g, b

  local i = math.floor(h * 6);
  local f = h * 6 - i;
  local p = v * (1 - s);
  local q = v * (1 - f * s);
  local t = v * (1 - (1 - f) * s);

  i = i % 6

  if i == 0 then r, g, b = v, t, p
  end
  if i == 1 then r, g, b = q, v, p
  end
  if i == 2 then r, g, b = p, v, t
  end
  if i == 3 then r, g, b = p, q, v
  end
  if i == 4 then r, g, b = t, p, v
  end
  if i == 5 then r, g, b = v, p, q
  end

	R=round((r*255),0)
	G=round((g*255),0)
	B=round((b*255),0)
  return R, G, B
end




function RGBtoHSV(r, g, b)
  r, g, b = r / 255, g / 255, b / 255
  local max, min = math.max(r, g, b), math.min(r, g, b)
  local h, s, v
  v = max

  local d = max - min
  if max == 0 then s = 0 else s = d / max end

  if max == min then
    h = 0 -- achromatic
  else
    if max == r then
    h = (g - b) / d
    if g < b then h = h + 6 end
    elseif max == g then h = (b - r) / d + 2
    elseif max == b then h = (r - g) / d + 4
    end
    h = h / 6
  end

  return h, s, v
end

function round(num, idp)
  local mult = 10^(idp or 0)
  return math.floor(num * mult + 0.5) / mult
end

function num2hex(num)
    local hexstr = '0123456789ABCDEF'
    local s = ''
    while num > 0 do
        local mod = math.fmod(num, 16)
        s = string.sub(hexstr, mod+1, mod+1) .. s
        num = math.floor(num / 16)
    end
    if s == '' then s = '0' end
    return s
end

t = hueread(device, params, mode)
processJSON(t)
return commandArray
I use a watchdog script, where this is a simplified version of, currently I have 5 ESP units in this watchdog script
Spoiler: show

Code: Select all

commandArray = {}

PRINT_MODE = false		-- when true wil print output to log and send notifications

function timedifference (s)
  year = string.sub(s, 1, 4)
  month = string.sub(s, 6, 7)
  day = string.sub(s, 9, 10)
  hour = string.sub(s, 12, 13)
  minutes = string.sub(s, 15, 16)
  seconds = string.sub(s, 18, 19)
  t1 = os.time()
  t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
  difference = os.difftime (t1, t2)
  return difference
end

LastupdateESP = otherdevices_lastupdate['HeartbeatESP']
ESPdifference=timedifference (LastupdateESP)
	if PRINT_MODE == true then
	    print('Lastupdate ESP ' .. LastupdateESP)
        print('Time difference ' .. ESPdifference)
    end
    
if (ESPdifference>=130) then
    if (otherdevices['ESPAlive'] == 'On')then
        commandArray['ESPAlive'] = 'Off'
        CurrentTime=os.date("%Y-%m-%d %H:%M:%S")
        file = io.open("/home/pi/domoticz/www/log/MysensorWatchdog.log", "a")
            io.output(file)
            io.write(CurrentTime.. " Mysensor ESP connection lost" .. "\n")
            io.close(file)
        	if PRINT_MODE == true then
                print('Writing to error log')
            end
    end
end
if (ESPdifference<130 and otherdevices['ESPAlive'] == 'Off')then
	if PRINT_MODE == true then
        print('ESP is a live again')
    end
    commandArray['ESPAlive'] = 'On'
    CurrentTime=os.date("%Y-%m-%d %H:%M:%S")
    file = io.open("/home/pi/domoticz/www/log/MysensorWatchdog.log", "a")
        io.output(file)
        io.write(CurrentTime.. " Mysensor ESP connection operational again" .. "\n")
        io.close(file)
    	if PRINT_MODE == true then
            print('Writing to error log')
        end
end


            commandArray['HeartbeatESP'] = 'On'
return commandArray
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest