206 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
 | 
						|
////////////////////////////////////
 | 
						|
//   DEVICE-SPECIFIC LED SERVICES //
 | 
						|
////////////////////////////////////
 | 
						|
 | 
						|
#include "extras/PwmPin.h"                          // library of various PWM functions
 | 
						|
 | 
						|
////////////////////////////////////
 | 
						|
 | 
						|
struct DEV_LED : Service::LightBulb {               // ON/OFF LED
 | 
						|
 | 
						|
  int ledPin;                                       // pin number defined for this LED
 | 
						|
  SpanCharacteristic *power;                        // reference to the On Characteristic
 | 
						|
  
 | 
						|
  DEV_LED(int ledPin) : Service::LightBulb(){       // constructor() method
 | 
						|
 | 
						|
    power=new Characteristic::On();                 
 | 
						|
    this->ledPin=ledPin;                            
 | 
						|
    pinMode(ledPin,OUTPUT);                         
 | 
						|
    
 | 
						|
    Serial.print("Configuring On/Off LED: Pin=");   // initialization message
 | 
						|
    Serial.print(ledPin);
 | 
						|
    Serial.print("\n");
 | 
						|
 | 
						|
  } // end constructor
 | 
						|
 | 
						|
  StatusCode update(){                              // update() method
 | 
						|
 | 
						|
    LOG1("Updating On/Off LED on pin=");
 | 
						|
    LOG1(ledPin);
 | 
						|
    LOG1(":  Current Power=");
 | 
						|
    LOG1(power->getVal()?"true":"false");
 | 
						|
    LOG1("  New Power=");
 | 
						|
    LOG1(power->getNewVal()?"true":"false");
 | 
						|
    LOG1("\n");
 | 
						|
 | 
						|
    digitalWrite(ledPin,power->getNewVal());      
 | 
						|
   
 | 
						|
    return(StatusCode::OK);                         // return OK status code
 | 
						|
  
 | 
						|
  } // update
 | 
						|
};
 | 
						|
      
 | 
						|
//////////////////////////////////
 | 
						|
 | 
						|
struct DEV_DimmableLED : Service::LightBulb {       // Dimmable LED
 | 
						|
 | 
						|
  PwmPin *pwmPin;                                   // reference to PWM Pin
 | 
						|
  int ledPin;                                       // pin number defined for this LED
 | 
						|
  int channel;                                      // PWM channel used for this LED (should be unique for each LED)
 | 
						|
  SpanCharacteristic *power;                        // reference to the On Characteristic
 | 
						|
  SpanCharacteristic *level;                        // reference to the Brightness Characteristic
 | 
						|
  
 | 
						|
  DEV_DimmableLED(int channel, int ledPin) : Service::LightBulb(){       // constructor() method
 | 
						|
 | 
						|
    power=new Characteristic::On();     
 | 
						|
                
 | 
						|
    level=new Characteristic::Brightness(50);       // Brightness Characteristic with an initial value of 50%
 | 
						|
    new SpanRange(5,100,1);                         // sets the range of the Brightness to be from a min of 5%, to a max of 100%, in steps of 1%
 | 
						|
 | 
						|
    this->channel=channel;                          // save the channel number (from 0-15)
 | 
						|
    this->ledPin=ledPin;                            // save LED pin number
 | 
						|
    this->pwmPin=new PwmPin(channel, ledPin);       // configure the PWM channel and attach the specified ledPin
 | 
						|
 | 
						|
    Serial.print("Configuring Dimmable LED: Pin="); // initialization message
 | 
						|
    Serial.print(ledPin);
 | 
						|
    Serial.print(" Channel=");
 | 
						|
    Serial.print(channel);
 | 
						|
    Serial.print("\n");
 | 
						|
    
 | 
						|
  } // end constructor
 | 
						|
 | 
						|
  StatusCode update(){                              // update() method
 | 
						|
 | 
						|
    LOG1("Updating Dimmable LED on pin=");
 | 
						|
    LOG1(ledPin);
 | 
						|
    LOG1(":  Current Power=");
 | 
						|
    LOG1(power->getVal()?"true":"false");
 | 
						|
    LOG1("  Current Brightness=");
 | 
						|
    LOG1(level->getVal());
 | 
						|
  
 | 
						|
    if(power->updated()){
 | 
						|
      LOG1("  New Power=");
 | 
						|
      LOG1(power->getNewVal()?"true":"false");
 | 
						|
    }
 | 
						|
 | 
						|
    if(level->updated()){
 | 
						|
      LOG1("  New Brightness=");
 | 
						|
      LOG1(level->getNewVal());
 | 
						|
    } 
 | 
						|
 | 
						|
    LOG1("\n");
 | 
						|
    
 | 
						|
    pwmPin->set(channel,power->getNewVal()*level->getNewVal());    
 | 
						|
   
 | 
						|
    return(StatusCode::OK);                         // return OK status code
 | 
						|
  
 | 
						|
  } // update
 | 
						|
};
 | 
						|
      
 | 
						|
//////////////////////////////////
 | 
						|
 | 
						|
struct DEV_RgbLED : Service::LightBulb {       // RGB LED (Command Cathode)
 | 
						|
 | 
						|
  PwmPin *redPin, *greenPin, *bluePin;
 | 
						|
  int redChannel, greenChannel, blueChannel;
 | 
						|
  
 | 
						|
  SpanCharacteristic *power;                   // reference to the On Characteristic
 | 
						|
  SpanCharacteristic *H;                       // reference to the Hue Characteristic
 | 
						|
  SpanCharacteristic *S;                       // reference to the Saturation Characteristic
 | 
						|
  SpanCharacteristic *V;                       // reference to the Brightness Characteristic
 | 
						|
  
 | 
						|
  DEV_RgbLED(int redChannel, int greenChannel, int blueChannel, int redPin, int greenPin, int bluePin) : Service::LightBulb(){       // constructor() method
 | 
						|
 | 
						|
    power=new Characteristic::On();                    
 | 
						|
    H=new Characteristic::Hue(0);              // instantiate the Hue Characteristic with an initial value of 0 out of 360
 | 
						|
    S=new Characteristic::Saturation(0);       // instantiate the Saturation Characteristic with an initial value of 0%
 | 
						|
    V=new Characteristic::Brightness(100);     // instantiate the Brightness Characteristic with an initial value of 100%
 | 
						|
    new SpanRange(5,100,1);                    // sets the range of the Brightness to be from a min of 5%, to a max of 100%, in steps of 1%
 | 
						|
 | 
						|
    this->redChannel=redChannel;               // save the channel number (from 0-15)
 | 
						|
    this->greenChannel=greenChannel;           
 | 
						|
    this->blueChannel=blueChannel;            
 | 
						|
    
 | 
						|
    this->redPin=new PwmPin(redChannel, redPin);        // instantiate the PWM channel and attach the specified pin
 | 
						|
    this->greenPin=new PwmPin(greenChannel, greenPin);
 | 
						|
    this->bluePin=new PwmPin(blueChannel, bluePin);
 | 
						|
 | 
						|
    char cBuf[128];
 | 
						|
    sprintf(cBuf,"Configuring RGB LED: Pins=(%d,%d,%d)  Channels=(%d,%d,%d)\n",redPin,greenPin,bluePin,redChannel,greenChannel,blueChannel);
 | 
						|
    Serial.print(cBuf);
 | 
						|
    
 | 
						|
  } // end constructor
 | 
						|
 | 
						|
  StatusCode update(){                         // update() method
 | 
						|
 | 
						|
    boolean p;
 | 
						|
    float v, h, s, r, g, b;
 | 
						|
 | 
						|
    h=H->getVal<float>();                      // get and store all current values.  Note the use of the <float> template to properly read the values
 | 
						|
    s=S->getVal<float>();
 | 
						|
    v=V->getVal<float>();                      // though H and S are defined as FLOAT in HAP, V (which is brightness) is defined as INT, but will be re-cast appropriately
 | 
						|
    p=power->getVal();
 | 
						|
 | 
						|
    char cBuf[128];
 | 
						|
    sprintf(cBuf,"Updating RGB LED on pins=(%d,%d,%d): ",redPin->getPin(),greenPin->getPin(),bluePin->getPin());
 | 
						|
    LOG1(cBuf);
 | 
						|
 | 
						|
    if(power->updated()){
 | 
						|
      p=power->getNewVal();
 | 
						|
      sprintf(cBuf,"Power=%s->%s, ",power->getVal()?"true":"false",p?"true":"false");
 | 
						|
    } else {
 | 
						|
      sprintf(cBuf,"Power=%s, ",p?"true":"false");
 | 
						|
    }
 | 
						|
    LOG1(cBuf);
 | 
						|
      
 | 
						|
    if(H->updated()){
 | 
						|
      h=H->getNewVal<float>();
 | 
						|
      sprintf(cBuf,"H=%.0f->%.0f, ",H->getVal<float>(),h);
 | 
						|
    } else {
 | 
						|
      sprintf(cBuf,"H=%.0f, ",h);
 | 
						|
    }
 | 
						|
    LOG1(cBuf);
 | 
						|
 | 
						|
    if(S->updated()){
 | 
						|
      s=S->getNewVal<float>();
 | 
						|
      sprintf(cBuf,"S=%.0f->%.0f, ",S->getVal<float>(),s);
 | 
						|
    } else {
 | 
						|
      sprintf(cBuf,"S=%.0f, ",s);
 | 
						|
    }
 | 
						|
    LOG1(cBuf);
 | 
						|
 | 
						|
    if(V->updated()){
 | 
						|
      v=V->getNewVal<float>();
 | 
						|
      sprintf(cBuf,"V=%.0f->%.0f  ",V->getVal<float>(),v);
 | 
						|
    } else {
 | 
						|
      sprintf(cBuf,"V=%.0f  ",v);
 | 
						|
    }
 | 
						|
    LOG1(cBuf);
 | 
						|
 | 
						|
    // Here we call a static function of PwmPin that converts HSV to RGB.
 | 
						|
    // Parameters must all be floats in range of H[0,360], S[0,1], and V[0,1]
 | 
						|
    // R, G, B, returned [0,1] range as well
 | 
						|
 | 
						|
    PwmPin::HSVtoRGB(h,s/100.0,v/100.0,&r,&g,&b);   // since HomeKit provides S and V in percent, scale down by 100
 | 
						|
 | 
						|
    int R, G, B;
 | 
						|
 | 
						|
    R=p*r*100;                                      // since PwmPin uses percent, scale back up by 100, and multiple by status fo power (either 0 or 1)
 | 
						|
    G=p*g*100;
 | 
						|
    B=p*b*100;
 | 
						|
 | 
						|
    sprintf(cBuf,"RGB=(%d,%d,%d)\n",R,G,B);
 | 
						|
    LOG1(cBuf);
 | 
						|
 | 
						|
    redPin->set(redChannel,R);                      // update the PWM channels with new values
 | 
						|
    greenPin->set(greenChannel,G);    
 | 
						|
    bluePin->set(blueChannel,B);    
 | 
						|
      
 | 
						|
    return(StatusCode::OK);                         // return OK status code
 | 
						|
  
 | 
						|
  } // update
 | 
						|
};
 | 
						|
      
 | 
						|
//////////////////////////////////
 |