Hardware components | ||||||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
| × | 1 | ||||
![]() |
| × | 1 | |||
| × | 1 | ||||
![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
![]() |
| |||||
Hand tools and fabrication machines | ||||||
![]() |
| |||||
![]() |
|
You might ask why you would possibly need an automatic dog bed? Don't dog beds just sit there and wait for a dog to lay down? Technical people sometimes have the bad habit of over complicating things. Isn’t a regular dog bed good enough?
Although my dog is great, she has one habit that is annoying. Every time you get up from your seat, she runs over and takes it. Then, there is a long process, usually involving cajoling, treats or false promises of a walk to get her to move. Of course, she is a master of the puppy dog eyes. All that drama makes you feel like a heel.
I figured, if she had her own temperature appropriate place to be, she'd leave my place to me. That is the genesis of the automatic dog bed.
This bed has built in temperature and motion sensors. If it's cold and the dog is around, it automatically turns on a heating pad build into the cusion. If it's hot and the dog is present, it turns on a small fan.
The termperature threshold for heating and cooling is managed through the configuration window and the built in joy stick control.
The sign at the rear of the bed, lights up in different colors depending on what is going on (in dog appropriate colors)
/*
* Project DogBed
* Author: David Barbour
* Date: 3/1/24
*/
#include "Particle.h"
#include "IoTClassroom_CNM.h"
#include "neopixel.h"
#include "Colors.h"
#include "math.h"
#include "IoTTimer.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#include "Adafruit_BME280.h"
#include "Graphic.h"
#include "Button.h"
#include "wemo.h"
//CONSTANTS
//joystick
const int joyHorz = A1;
const int joyVert = A2;
const int joySwitch = D6;
//neo pixel
const int PIXELCOUNT = 20;
//temperature reading
const int SENSORWAITTINE=10;
//Motion detector
const int DETECTPIN=D9;
//hue light bulb
const int BULB=3;
//Variables
//joystick
int newVer;int newHor;int oldVer;int oldHor;
bool setVertDown = false;bool setVertUp = false;
bool setHorRight = false;bool setHorLeft = false;
Button joyButton(joySwitch,true);
//Neo pixels
Adafruit_NeoPixel pixel ( PIXELCOUNT , SPI1 , WS2812B );
//temperature reading
bool forceHeat = false;bool forceCool = false;
float coolingTemp = 74;float heatingTemp = 73;
float currentTemp;
bool status;
Adafruit_BME280 bme;
//display setup
Adafruit_SSD1306 display(-1);
bool showDisplay=false;
//timers
IoTTimer waitTimer;
int waitedTime=0;
//Motion detector
bool motionDetected=false;
//wemo device numbers
int wemoCool=4;int wemoHeat=2;
//hue light bulb
bool sendCmdToHue = true;
//debugging button
Button debugButton(D4,false);
//application and setup states
int applicationState=0;int prevApplicationState;
int setupState=0;int subSetupState=0;
//functions
void PixelFill(int startPixel, int endPixel, int theColor);
void setPixelDisplay(int theState);
void programLogic();
SYSTEM_MODE(MANUAL);
void setup() {
//start serial monitor
Serial.begin(9600);
waitFor (Serial.isConnected,10000);
//turn on wi fi
WiFi.on();
WiFi.clearCredentials();
WiFi.setCredentials("IoTNetwork");
WiFi.connect();
while(WiFi.connecting()) {
delay(50);
Serial.printf(".");}
//start the display
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
showDisplay=true;
//start the neo pixels
pixel.begin();
pixel.setBrightness(22);
pixel.clear();
pixel.show();
//set up motion detector
pinMode(DETECTPIN,INPUT);
//start bme temp guage
status=bme.begin (0x76);
if (status==false ) {
Serial.printf (" BME280 at address %c failed to start ", 0x76 );}
}
void loop()
{
programLogic();
}
void programLogic()
{
//There are multiple states the application can be in
// 0 - off
// 1 - setup mode
// 2 - waiting to cool
// 3 - cooling
// 4 - waiting to heat
// 5 - heating
//read the temperature
currentTemp = (bme.readTemperature ()*9/5)+32.0; // deg F
//this is for debugging only
if (debugButton.isClicked()==true){
//Serial.printf("Start %i, Temp %0.1f%cF\n\n",0,currentTemp,248);
Serial.printf("Application %i, SetupState %i \n",applicationState,setupState);
Serial.printf("Forcecool %i, forceheat %i motion %i\n",forceCool,forceHeat,motionDetected);
Serial.printf("Currenttemp %f, cooltemp %f heatingtemp %f\n",currentTemp,coolingTemp,heatingTemp);
Serial.printf("\n");
}
//determine what state you should be in
prevApplicationState = applicationState;
if (forceCool==true){
forceHeat=false;
applicationState=3;
setupState=0;
}
if (forceHeat==true){
forceCool = false;
applicationState = 5;
setupState=0;
}
//when you're in running mode
if(forceCool==false && forceHeat==false && applicationState>1){
//go throught the temperature and motion settings
if(currentTemp>=coolingTemp){
if (motionDetected==true){
applicationState=3;
}
else{
applicationState=2;
}
}
//if the temperature goes below the heating temp, turn on
if(currentTemp<heatingTemp)
{
if (motionDetected==true){
applicationState=5;
}
else{
applicationState=4;
}
}
}
//only update the display if something changes
if(applicationState!=prevApplicationState){showDisplay=true;}
switch (applicationState){
case 0:
//this is off
//turn off the neopixels
setPixelDisplay(0);
//turn off the display
if(showDisplay){
display.clearDisplay();
display.display();
showDisplay=false;
//turn off the heater
wemoWrite(wemoHeat,LOW);
//turn off the fan
wemoWrite(wemoCool,LOW);
}
//if user clicks on button, start running process
if (joyButton.isPressed()==true){
Serial.print("Push joystick button");
applicationState=1;
showDisplay=true;
}
//set these back to default off
forceHeat = false;
forceCool = false;
break;
case 1:
//setup mode
setPixelDisplay(1);
newVer = analogRead(joyVert);
newHor = analogRead(joyHorz);
switch (setupState){
case 0: //on off screen
if(showDisplay){
display.clearDisplay();
display.drawBitmap(20, 0,graphic_onoff, 80,68, 1);
display.display();
showDisplay=false;
//turn off the heater
wemoWrite(wemoHeat,LOW);
//turn off the fan
wemoWrite(wemoCool,LOW);
}
//DOWN set the application state back to off
if(newVer>3500){setVertDown=true;}
if(newVer<3500 && setVertDown==true){
applicationState = 0;
setVertDown = false;
showDisplay=true;
}
//UP turn it on
if(newVer<1500){setVertUp=true;}
if(newVer>1500 && setVertUp==true){
applicationState = 2;
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
showDisplay=true;
}
//RIGHT, go to the cooling teperature screen
if(newHor>3500){setHorRight=true;}
if(newHor<3500 && setHorRight==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
setupState = 1;
showDisplay=true;
}
//set these back to default off
forceHeat = false;
forceCool = false;
break;
case 1:
//set cooling termperature
//up down arrow
if (showDisplay){
display.clearDisplay();
display.drawBitmap(0, 9,graphic_updown,16,46, 1);
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(20,0);
display.printf("Set cooling temp");
display.setTextSize(2);
display.setCursor(60,25);
display.printf("%.0f",coolingTemp);
display.display();
showDisplay=false;
}
//RIGHT, go to the heating teperature screen
if(newHor>3500){setHorRight=true;}
if(newHor<3500 && setHorRight==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
setupState = 2;
showDisplay=true;
}
//LEFT, go to on off screen
if(newHor<1000){setHorLeft=true;}
if(newHor>1000 && setHorLeft==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
setupState = 0;
showDisplay=true;
}
//UP, increase the cooling termperature
if(newVer>3000){setVertUp=true;}
if(newVer<3000 && setVertUp==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
coolingTemp--;
//keep the temps from overlapping
if(heatingTemp>=coolingTemp){heatingTemp=coolingTemp-1.0;}
showDisplay=true;
}
//DOWN, decrease the cooling termperature
if(newVer<1000){setVertDown=true;}
if(newVer>1000 && setVertDown==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
coolingTemp++;
//keep the temps from overlapping
if(heatingTemp>=coolingTemp){heatingTemp=coolingTemp-1.0;}
showDisplay=true;
}
break;
case 2:
//set heting termperature
if(showDisplay){
display.clearDisplay();
display.drawBitmap(0, 9,graphic_updown,16,46, 1);
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(20,0);
display.printf("Set heating temp");
display.setTextSize(2);
display.setCursor(60,25);
display.printf("%.0f",heatingTemp);
display.display();
showDisplay=false;
}
//LEFT, go to on off screen
if(newHor<1000){setHorLeft=true;}
if(newHor>1000 && setHorLeft==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
setupState = 1;
showDisplay=true;
}
//UP, increase the heating termperature
if(newVer>3000){setVertUp=true;}
if(newVer<3000 && setVertUp==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
heatingTemp--;
//keep the temps from overlapping
if(heatingTemp>=coolingTemp){coolingTemp=heatingTemp+1.0;}
showDisplay=true;
}
//DOWN, increase the heating termperature
if(newVer<1000){setVertDown=true;}
if(newVer>1000 && setVertDown==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
heatingTemp++;
//keep the temps from overlapping
if(heatingTemp>=coolingTemp){coolingTemp=heatingTemp+1.0;}
showDisplay=true;
}
//Right, go to manual screen
if(newHor>3000){setHorRight=true;}
if(newHor<3000 && setHorRight==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
setupState = 3;
showDisplay=true;
}
break;
case 3:
//manual heat or cool
if(showDisplay){
display.clearDisplay();
display.drawBitmap(9, 5,graphic_hotcold,110,51, 1);
display.setTextColor(WHITE);
display.display();
showDisplay=false;
}
//UP, start heat
if(newVer<1000){setVertDown=true;}
if(newVer>1000 && setVertDown==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
forceHeat = true;
showDisplay=true;
}
//DOWN, start cooling
if(newVer>3000){setVertUp=true;}
if(newVer<3000 && setVertUp==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
forceCool = true;
showDisplay=true;
}
//LEFT, to the heat temp screen
if(newHor<1000){setHorLeft=true;}
if(newHor>1000 && setHorLeft==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
setupState = 2;
showDisplay=true;
}
break;
}
break;
case 2: //wating to cool
setPixelDisplay(2);
//tell the user, it's waiting to cool
if(showDisplay){
waitedTime = 0;
waitTimer.startTimer(1000);
motionDetected=0;
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(20,0);
display.printf("Waiting to cool");
display.display();
showDisplay=false;
}
//do a countdown, so the motion sensor doesn't start reading
//for 10 seconds
if (waitedTime < SENSORWAITTINE){
if (waitTimer.isTimerReady()==true){
display.fillRect(50,20, 70,30,BLACK);
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(50,20);
display.printf("%i",SENSORWAITTINE-waitedTime);
display.display();
waitedTime++;
waitTimer.startTimer(1000);
forceCool=false;forceHeat=false;
}
}
else{
//read the motion sensor
display.fillRect(50,20, 70,30,BLACK);
display.display();
motionDetected = digitalRead(DETECTPIN);
}
//LEFT, go back to setup screen
if(newHor<1000){setHorLeft=true;}
if(newHor>1000 && setHorLeft==true){
//Serial.print("Cooling left button");
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
applicationState = 1;
setupState=0;
waitedTime = 0;
motionDetected=false;
showDisplay=true;
forceCool=false;forceHeat=false;
}
break;
case 3: //Cooling
setPixelDisplay(3);
newHor = analogRead(joyHorz);
//tell the user, it's cooling
if(showDisplay){
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(20,0);
display.printf("Cooling");
display.display();
showDisplay=false;
//turn on fan here
wemoWrite(wemoCool,HIGH);
}
//LEFT, go back to setup screen
if(newHor<1000){setHorLeft=true;}
if(newHor>1000 && setHorLeft==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
applicationState = 1;
setupState=0;
waitedTime = 0;
motionDetected=false;
showDisplay=true;
forceCool=false;forceHeat=false;
}
break;
case 4: //Wating to heat
setPixelDisplay(4);
//tell the user, it's cooling
if(showDisplay){
waitedTime = 0;
waitTimer.startTimer(1000);
motionDetected=0;
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(20,0);
display.printf("Wating to heat");
display.display();
showDisplay=false;
}
//do a countdown, so the motion sensor doesn't
//start reading for 10 seconds
if (waitedTime < SENSORWAITTINE){
if (waitTimer.isTimerReady()==true){
display.fillRect(50,20, 70,30,BLACK);
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(50,20);
display.printf("%i",SENSORWAITTINE-waitedTime);
display.display();
waitedTime++;
waitTimer.startTimer(1000);
}
}
else
{
//read the motion sensor
display.fillRect(50,20, 70,30,BLACK);
display.display();
motionDetected = digitalRead(DETECTPIN);
}
//LEFT, go back to setup screen
if(newHor<1000){setHorLeft=true;}
if(newHor>1000 && setHorLeft==true){
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
applicationState = 1;
setupState=0;
waitedTime = 0;
motionDetected=false;
showDisplay=true;
forceCool=false;forceHeat=false;
}
break;
case 5: //heating
setPixelDisplay(5);
newHor = analogRead(joyHorz);
//tell the user, it's cooling
if(showDisplay){
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(20,0);
display.printf("Heating");
display.display();
showDisplay=false;
//turn on heater here
wemoWrite(wemoHeat,HIGH);
}
//LEFT, go back to setup screen
if(newHor<1000){setHorLeft=true;}
if(newHor>1000 && setHorLeft==true){
Serial.print("Heating left button");
setHorRight = false;setHorLeft= false;setVertDown=false;setVertUp=false;
applicationState = 1;
setupState=0;
waitedTime = 0;
motionDetected=false;
forceHeat=false;
showDisplay=true;
}
break;
default:
break;
}
}
void setPixelDisplay(int theState)
{
static int lastSwitch;
static bool onOff;
int brightNess;
bool useHue = true;
switch (theState)
{
case 0:
//bed is off
pixel.clear();
pixel.show();
if (useHue) {setHue(BULB,false,0,0,0);}
break;
case 1:
//setup mode (blinking white every second)
if(millis()-lastSwitch>500)
{
pixel.setBrightness(10);
onOff = !onOff;
if (onOff==true)
{
PixelFill(0,PIXELCOUNT-1,white);
if (useHue) {setHue(BULB,true,HueOrange,75,10);}
}
else
{
pixel.clear();
if (useHue) {setHue(BULB,false,0,0,0);}
}
pixel.show();
lastSwitch = millis();
}
break;
case 2:
// bed is ready to be cold (breath blue)
PixelFill(0,PIXELCOUNT-1,blue);
brightNess = 7 * sin(2.0*M_PI*(2.0/5.0)*millis()/1000.0)+ 10;
pixel.setBrightness(brightNess);
pixel.show();
if (useHue) {setHue(BULB,true,HueBlue,brightNess,255);}
break;
case 3:
//bed is in cold mode (steady blue)
PixelFill(0,PIXELCOUNT-1,blue);
pixel.setBrightness(40);
pixel.show();
if (useHue) {setHue(BULB,true,HueBlue,100,255);}
break;
case 4:
// bed is ready to be hot (breathing yellow)
PixelFill(0,PIXELCOUNT-1,yellow);
brightNess = 7 * sin(2.0*M_PI*(2.0/5.0)*millis()/1000.0)+ 10;
pixel.setBrightness(brightNess);
pixel.show();
if (useHue) {setHue(BULB,true,HueYellow,brightNess,255);}
break;
case 5:
//bed is in heat mode (steady yellow)
PixelFill(0,PIXELCOUNT-1,yellow);
pixel.setBrightness(40);
pixel.show();
if (useHue) {setHue(BULB,true,HueYellow,100,255);}
break;
default:
//bed is off
pixel.clear();
pixel.show();
if (useHue) {setHue(BULB,false,0,0,0);}
break;
}
}
void PixelFill(int startPixel, int endPixel, int theColor)
{
int theLoop;
for (theLoop=startPixel;theLoop<=endPixel;theLoop++){
pixel.setPixelColor(theLoop,theColor);
}
}
#ifndef _BUTTON_H_
#define _BUTTON_H_
class Button {
int _buttonPin;
int _prevButtonState;
bool _pullUp;
public:
Button(int buttonPin, bool pullUp=false) {
_buttonPin = buttonPin;
_pullUp = pullUp;
if(pullUp) {
pinMode(_buttonPin,INPUT_PULLUP);
}
else {
pinMode(_buttonPin,INPUT_PULLDOWN);
}
}
bool isPressed() {
bool _buttonState;
_buttonState = digitalRead(_buttonPin);
if(_pullUp) {
_buttonState = !_buttonState;
}
return _buttonState;
}
bool isClicked() {
bool _buttonState, _clicked;
_buttonState = digitalRead(_buttonPin);
if(_pullUp) {
_buttonState = !_buttonState;
}
if(_buttonState != _prevButtonState) {
_clicked = _buttonState;
}
else {
_clicked = false;
}
_prevButtonState=_buttonState;
return _clicked;
}
};
#endif // _BUTTON_H_
/*
* Project: colors.h
* Description: Header file for color mapping
* Brian Rashap
* 10-Feb-2020
*/
#ifndef _COLORS_H_
#define _COLORS_H_
const int black = 0x000000;
const int white = 0xFFFFFF;
const int red = 0xFF0000;
const int lime = 0x00FF00;
const int blue = 0x0000FF;
const int yellow = 0xFFFF00;
const int cyan = 0x00FFFF;
const int magenta = 0xFF00FF;
const int silver = 0xC0C0C0;
const int gray = 0x808080;
const int maroon = 0x800000;
const int olive = 0x808000;
const int green = 0x008000;
const int purple = 0x800080;
const int teal = 0x008080;
const int navy = 0x000080;
const int orange = 0xFFA500;
const int indigo = 0x4B0082;
const int violet = 0x9400D3;
const int maize = 0xF2C649;
const int pink = 0xFFC0CB;
const int turquoise = 0x40E0D0;
const int carrot = 0xED9121;
const int chocolate = 0xD2691E;
const int salmon = 0xC67171;
const int tomato = 0xFF6347;
const int rainbow[] = {red, orange, yellow, green, blue, indigo,violet};
#endif // _COLORS_H_
#ifndef _GRAPHIC_H_
#define _GRAPHIC_H_
static const unsigned char graphic_updown[]={// 'UpDown, 16x46px
0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03,
0xf0, 0x0f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x0f, 0xf8, 0x1f, 0xf8, 0x1f,
0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f,
0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f,
0xf0, 0x0f, 0xf8, 0x1f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03, 0xe0, 0x07,
0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff};
static const unsigned char graphic_off[] ={// 'Off, 65x61px
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff,
0xff, 0xff, 0x07, 0x06, 0x0f, 0xff, 0xff, 0x80, 0xff, 0xff, 0xfe, 0xf7, 0x3e, 0xff, 0xff, 0xff,
0x80, 0xff, 0xff, 0xfd, 0xfb, 0x7e, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xfd, 0xfb, 0x3e, 0x7f,
0xff, 0xff, 0x80, 0xff, 0xff, 0xfd, 0xfb, 0x06, 0x0f, 0xff, 0xff, 0x80, 0xff, 0xff, 0xfd, 0xfb,
0x3e, 0x7f, 0xff, 0xff, 0x80, 0xff, 0xff, 0xfd, 0xfb, 0x3e, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff,
0xfe, 0xf7, 0x3e, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x0f, 0x3e, 0xff, 0xff, 0xff, 0x80,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff,
0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00,
0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff,
0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80,
0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff,
0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03,
0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff,
0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff,
0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff,
0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff,
0xff, 0xff, 0x80, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x9f, 0xff, 0xff, 0x80, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0x80, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0xff, 0xff,
0xf0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80,
0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff,
0xff, 0x80, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x80, 0x07,
0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff,
0xe0, 0x1f, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0x80, 0xff,
0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80};
static const unsigned char graphic_onoff[] = { //80 x 68
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe1, 0xc3, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xdf, 0x43, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xdf, 0xff, 0x7f, 0xff, 0xff, 0xff,
0xfe, 0x3f, 0xff, 0xff, 0xde, 0xdf, 0x7f, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xed, 0xdf,
0x7f, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x07,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x00, 0x00, 0x3f, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x03,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x07, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff,
0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff,
0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03,
0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01,
0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff,
0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff,
0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03,
0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01,
0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xe0,
0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,
0xc0, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xfe, 0x00, 0x00,
0x7f, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01,
0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x0b, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0x7b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xb9, 0xdf, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xd9, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
0xde, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xde, 0x5f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf7, 0xdf, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xbf, 0x9f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
// 'HeatCool', 110x51px
static const unsigned char graphic_hotcold[] = { //110 x 51
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x0f, 0xfc, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc,
0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xff, 0xc0,
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xff, 0x80, 0x07, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xc0, 0x0f, 0xfc, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x0f, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc,
0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xff, 0xc0,
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xff, 0xc0, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x07, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3,
0xfc, 0x00, 0x00, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xc7, 0xc7, 0xff, 0xff, 0xff, 0xf3, 0xfe, 0x00,
0x00, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xc7, 0x87, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x00, 0x01, 0xfc,
0xff, 0xc0, 0x0f, 0xff, 0xc3, 0x86, 0x1d, 0x19, 0xd8, 0x73, 0xff, 0x80, 0x03, 0xfc, 0xff, 0xc0,
0x0f, 0xff, 0xd3, 0x26, 0x8c, 0x19, 0xd9, 0x33, 0xff, 0xc0, 0x07, 0xfc, 0xff, 0xc0, 0x0f, 0xff,
0xdb, 0x27, 0x0d, 0xc9, 0xdc, 0x33, 0xff, 0xe0, 0x0f, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xd8, 0x66,
0x0d, 0xc9, 0xd8, 0x33, 0xff, 0xf0, 0x1f, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xd8, 0x64, 0xcd, 0xc9,
0x99, 0xb3, 0xff, 0xf8, 0x7f, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xdc, 0x64, 0x0d, 0xcc, 0x18, 0x33,
0xff, 0xfc, 0x7f, 0xfc, 0xff, 0xc0, 0x0f, 0xff, 0xdc, 0xe6, 0x0d, 0xcc, 0x5c, 0x33, 0xff, 0xff,
0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0xfd, 0xdf, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0x7c, 0xf9, 0xdf,
0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0x7c, 0xf9, 0xd8, 0x63, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf0, 0xc3, 0x7c, 0xf8, 0x13, 0x79, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf9, 0xe6, 0xd9, 0x7c, 0xf9, 0x90, 0x61, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf9, 0xe6, 0x99, 0x7c, 0xf9, 0x93, 0xc9, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf9, 0xe6, 0xdb, 0x7c, 0xf9, 0xd8, 0x61, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x30,
0xc3, 0x7c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc
};
#endif // _GRAPHIC_H_
#ifndef _HUE_H_
#define _HUE_H_
/*
* Project: Hue IoT Library
* Description: Library for controlling Hue Lights at IOT Classroom
* Authors: Brian Rashap
* Date: 1-MAY-2020
*/
#include "application.h"
/* Usage:
* setHue(int lightNum, bool HueOn, int HueColor, int HueBright, int HueSat);
* where:
* lightNum is the number of the light to be controlled
* HueOn is true to turn the light on, false to turn it off
* HueColor is a number between 0 and 65353 (see constants below)
* HueBright is the brightness between 0 and 255
* HueSat is the saturation between 0 and 255
*
* NOTE: In your main code, Ethernet.begin(mac) needs to be called
*/
// Hue Configuration
const char hueHubIP[] = "192.168.1.5"; // Hue hub IP
const char hueUsername[] = "MQlZziRO0Wai5MsMHll8xAUAQqw85Qrr8tM37F3T";
const int hueHubPort = 80; // HTTP: 80, HTTPS: 443, HTTP-PROXY: 8080
// Hue variables
bool hueOn; // on/off
int hueBri; // brightness value
long hueHue; // hue value
String hueCmd; // Hue command
// Hue colors
int HueRed = 0;
int HueOrange = 5000;
int HueYellow = 10000;
int HueGreen = 22500;
int HueBlue = 45000;
int HueIndigo = 47500;
int HueViolet = 50000;
int HueRainbow[] = {HueRed, HueOrange, HueYellow, HueGreen, HueBlue, HueIndigo, HueViolet};
TCPClient HueClient;
bool setHue(int lightNum, bool HueOn, int HueColor=HueBlue, int HueBright=255, int HueSat=255);
bool getHue(int lightNum);
bool setHue(int lightNum, bool HueOn, int HueColor, int HueBright, int HueSat) {
static int PrevLightNum,PrevOn, PrevColor, PrevBright, PrevSat;
String command = "";
if((lightNum==PrevLightNum)&&(HueOn==PrevOn)&&(HueColor==PrevColor)&&(HueBright==PrevBright)&&(HueSat==PrevSat)) {
Serial.printf("No Change - Cancelling CMD\n");
return false;
}
PrevLightNum = lightNum;
PrevOn = HueOn;
PrevColor=HueColor;
PrevBright=HueBright;
PrevSat=HueSat;
if(HueOn == true) {
/*
command = "{\"on\":true,\"sat\":255,\"bri\":255,\"hue\":";
command = command + String(HueColor) + "}";
*/
command = "{\"on\":true,\"sat\":";
command = command + String(HueSat) + ",\"bri\":";
command = command + String(HueBright) + ",\"hue\":";
command = command + String(HueColor) + "}";
}
else {
command = "{\"on\":false}";
}
if (HueClient.connect(hueHubIP, hueHubPort)) {
//while (HueClient.connected())
//{
// Serial.println("Sending Command to Hue");
// Serial.println(command);
Serial.printf("Sending Command to Hue: %s\n",command.c_str());
HueClient.print("PUT /api/");
HueClient.print(hueUsername);
HueClient.print("/lights/");
HueClient.print(lightNum); // hueLight zero based, add 1
// HueClient.println("/state");
HueClient.println("/state HTTP/1.1");
HueClient.println("keep-alive");
HueClient.print("Host: ");
HueClient.println(hueHubIP);
HueClient.print("Content-Length: ");
HueClient.println(command.length());
HueClient.println("Content-Type: text/plain;charset=UTF-8");
HueClient.println(); // blank line before body
HueClient.println(command); // Hue command
HueClient.readString();
// Serial.println("From Hue");
// Serial.println(HueClient.readString()); // To close connection
HueClient.stop();
return true; // command executed
}
else
return false; // command failed
}
bool getHue(int lightNum) {
if (HueClient.connect(hueHubIP, hueHubPort))
{
HueClient.print("GET /api/");
HueClient.print(hueUsername);
HueClient.print("/lights/");
HueClient.print(lightNum);
HueClient.println(" HTTP/1.1");
HueClient.print("Host: ");
HueClient.println(hueHubIP);
HueClient.println("Content-type: application/json");
HueClient.println("keep-alive");
HueClient.println();
//while (HueClient.connected())
//{
// if (HueClient.available()) {
Serial.println();
Serial.println(HueClient.readString());
Serial.println();
HueClient.findUntil("\"on\":", "\0");
hueOn = (HueClient.readStringUntil(',') == "true"); // if light is on, set variable to true
Serial.print("Hue Status: ");
Serial.println(hueOn);
HueClient.findUntil("\"bri\":", "\0");
hueBri = HueClient.readStringUntil(',').toInt(); // set variable to brightness value
Serial.println(hueBri);
HueClient.findUntil("\"hue\":", "\0");
hueHue = HueClient.readStringUntil(',').toInt(); // set variable to hue value
Serial.printf("Hue is\n\n\n %i\n",hueHue);
//break; // not capturing other light attributes yet
// }
//}
HueClient.stop();
return true; // captured on,bri,hue
}
else
return false; // error reading on,bri,hue
}
#endif // _HUE_H_
#ifndef _IOTTIMER_H_
#define _IOTTIMER_H_
class IoTTimer {
unsigned int _timerStart, _timerTarget;
public:
//IoT Constructor with no parameters
//IotTimer() {}
void startTimer(unsigned int msec) {
_timerStart = millis();
_timerTarget = msec;
}
bool isTimerReady() {
return ((millis() - _timerStart) >= _timerTarget);
}
};
#endif // _IOTTIMER_H_
#ifndef _WEMO_H_
#define _WEMO_H_
/*
* Project: Wemo IoT Library
* Description: Library for controlling Wemo Smart Outlets at IOT Classroom
* Authors: Brian Rashap
* Date: 06-FEB-2022
*/
#include "application.h"
TCPClient WemoClient;
int wemoPort = 49153;
const char *wemoIP[6] = {"192.168.1.30","192.168.1.31","192.168.1.32","192.168.1.33","192.168.1.34","192.168.1.35"};
// Function Prototypes
void switchON(int wemo);
void switchOFF(int wemo);
void wemoWrite(int outlet, bool wemoState);
// Turn on/off wemo outlets similar to digitalWrite
void wemoWrite(int outlet, bool wemoState) {
if(wemoState) {
switchON(outlet);
}
else {
switchOFF(outlet);
}
}
// turn on specified wemo outlet
void switchON(int wemo) {
String data1;
Serial.printf("Switching On Wemo #%i\n",wemo);
data1+="<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"><BinaryState>1</BinaryState></u:SetBinaryState></s:Body></s:Envelope>"; // Use HTML encoding for comma's
if (WemoClient.connect(wemoIP[wemo],wemoPort)) {
WemoClient.println("POST /upnp/control/basicevent1 HTTP/1.1");
WemoClient.println("Content-Type: text/xml; charset=utf-8");
WemoClient.println("SOAPACTION: \"urn:Belkin:service:basicevent:1#SetBinaryState\"");
WemoClient.println("Connection: keep-alive");
WemoClient.print("Content-Length: ");
WemoClient.println(data1.length());
WemoClient.println();
WemoClient.print(data1);
WemoClient.println();
}
if (WemoClient.connected()) {
WemoClient.stop();
}
}
// turn off wemo outlet specified
void switchOFF(int wemo){
String data1;
Serial.printf("Switching Off Wemo #%i \n",wemo);
data1+="<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"><BinaryState>0</BinaryState></u:SetBinaryState></s:Body></s:Envelope>"; // Use HTML encoding for comma's
if (WemoClient.connect(wemoIP[wemo],wemoPort)) {
WemoClient.println("POST /upnp/control/basicevent1 HTTP/1.1");
WemoClient.println("Content-Type: text/xml; charset=utf-8");
WemoClient.println("SOAPACTION: \"urn:Belkin:service:basicevent:1#SetBinaryState\"");
WemoClient.println("Connection: keep-alive");
WemoClient.print("Content-Length: ");
WemoClient.println(data1.length());
WemoClient.println();
WemoClient.print(data1);
WemoClient.println();
}
if (WemoClient.connected()) {
WemoClient.stop();
}
}
#endif // _WEMO_H_
Comments