Hi all,
Received my Spark Core yesterday with the intention of creating a motion sensor that I can use along side my Philips Hue Lighting Setup to turn off the lights in my room after it has been empty for a short amount of time.
Hardware:
Using 2 Parallax PIR sensors + a spark core.
Software:
Using a PHP library for my Philips Hue that I am in the process of creating.
https://github.com/markp1989/HuePhpLibrary
Code that is running on the Spark.
/*
Using Parallax PIR sensor
*/
int interval = 600000; //600 seconds
//both these vars are set to volatile because they will be changed when there is an interupt
volatile boolean motion = false;
volatile unsigned long lastmotiontime = 0;
boolean currentMotion = false; //variable that is going to be available through the spark api a nonvolatile var is required
void setup(){
Serial.begin(9600);
Spark.variable("motion", ¤tMotion , BOOLEAN);
//pinMode(pirPin, INPUT);
delay(30000);
Serial.println("setup has completed");
//attaching interrupt pins for both my motion sensors.
attachInterrupt(A0, motionInterupt, RISING);
attachInterrupt(A1, motionInterupt, RISING);
}
void loop(){
noInterrupts();
unsigned long currentMillis = millis();
//as I intend to have this on at all times adding in a catch for when the millis() function overflows.
if (currentMillis < lastmotiontime){
lastmotiontime = 0 ;
motion = false;
}
//reseting motion variable if no motion has been detected in a while
if (motion & (currentMillis - lastmotiontime > interval)){
Serial.print("no motion since ");
Serial.print(lastmotiontime);
Serial.println(" resetting state..........");
motion = false;
}
interrupts();
currentMotion = motion; //store the current state in a non volatile variable - for access from spark.variable
delay(10);
}
void motionInterupt(){
motion=true;
lastmotiontime = millis();
}
PHP Script Running on Home Server:
This script is called by Cron every 10minutes, does a few things:
-
- Adjusts the colour temperature of light to mimic natural sunlight
-
- Detects if the room is empty (using spark) and turns off the lights
-
- Will only do this if there is no content being played on the HTPC
This is the important bit for this part of the project which uses the spark API to read the “currentMotion” variable from the core:
$content = file_get_contents("https://api.spark.io/v1/devices/DEVID/motion?access_token=ACCESSTOKEN");
if (empty($content)) {
echo "catch if the motion sensor doesnt responde" . PHP_EOL;
} else {
$content = json_decode($content, true);
$roomEmpty = $content["result"];
if (!$roomEmpty) {
echo "the room is currently empty turning lights off. " . PHP_EOL;
$this->ph->on(false);
$this->ph->sendCommands();
return;
}
}
This is the full “Natural Light” Script
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of naturalLight
*
* This is mainly written for my own personal use, for a natural light script
* see the original "natural light" file.
*
* Does everything that the original natural light file did, but adds a couple
* of extra features:
*
* Description of naturalLight
* Sets a colour temperature to be similar to that of natural light
* 2500k at sun rise, gradually getting up to 6500k at midday
* then back to 2500k again at night.
*
* to be ran like :
* $nl = new naturalLight();
* $hour = date('G');
* $min = date('i');
* $nl->setLights($hour,$min);
*
* Currenly sun rise and sun set times need to be set manually
* Currently working:
* Only change the light temperature if there is nothing playing on XBMC.
*
* Planned:
* Turn the lights off if there is nobody in the room.
*
* @author Mark
*/
include_once "PhilipsHue.php";
include_once "xbmc.php";
class naturalLight {
private $sunrise = 7;
private $sunriseMin = 30;
private $midDay = 18;
private $midDayMin = 30;
//10:30 pm
private $sunset = 22;
private $sunsetMin = 30;
// reference color temperatures.
private $SunRiseSet = 2500;
private $Noon = 6500;
private $xbmcSettings = array('host' => 'markhtpc.local', 'port' => '8080', 'user' => 'xbmc', 'pass' => 'xbmc');
// -----------------------END OF configurable settings ----------------------------------------------------------
private $ph;
function __construct() {
$this->sunrise = ($this->sunrise * 3600) + ($this->sunriseMin * 60);
$this->sunset = ($this->sunset * 3600) + ($this->sunsetMin * 60 );
$this->midDay = ($this->midDay * 3600) + ($this->midDayMin * 60 );
$this->ph = new PhilipsHue();
//$this->ph->setup();
//$this->dayLength = $this->sunset - $this->sunrise;
//$this->midDay = ($this->sunrise + $this->sunset) / 2;
// echo "mid day is $this->midDay" . PHP_EOL;
}
/* input time in 24 hour format and any lights that are currently on
* will be set to the colour temperature representing the time between sunset.
*/
function setLights($hours, $mins, $roomEmpty = false) {
$this->ph->refreshLights(); //ensure that we have the latest state of the lights
/* if none of the lights are on just exit the function. */
if (!$this->ph->isOn()) {
echo "no lights are on! " . PHP_EOL;
return;
}
/* detect if any of the lights are in XY
* color mode and exit if they are
*/
$this->ph->refreshLights(); //ensure that we have the latest state of the lights
$modes = $this->ph->readModes();
print_r($modes);
if ($modes['XY'] > 0) {
echo "Lights are in a unsupported mode! " . PHP_EOL;
return;
}
/* Dont do anythign to the lights if there is something playing on the
* xbmc box.
*/
try {
$xbmcHost = new xbmcHost($this->xbmcSettings);
$xbmcJSON = new xbmcJson($xbmcHost);
$activePLayers = $xbmcJSON->Player->GetActivePlayers();
//dont change the lights if the media center is playing!!
if (!empty($activePLayers)) {
echo "Something is playing on the HTPC" . PHP_EOL;
return;
}
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$this->ph->refreshLights(); //ensure that we have the latest state of the lights
/* turn of the lights if the room is empty
* waiting for the Spark Core to be delivered
* so I can create a motion sensor.
*/
$content = file_get_contents("https://api.spark.io/v1/devices/DEVID/motion?access_token=ACCESSTOKEN");
if (empty($content)) {
echo "catch if the motion sensor doesnt responde" . PHP_EOL;
} else {
$content = json_decode($content, true);
$roomEmpty = $content["result"];
if (!$roomEmpty) {
echo "the room is currently empty turning lights off. " . PHP_EOL;
$this->ph->on(false);
$this->ph->sendCommands();
return;
}
}
$this->ph->refreshLights(); //ensure that we have the latest state of the lights
$birghtness = (int) $this->ph->getAvgBrightness();
//convert time to sec Since midnight.
$time = ($hours * 60 * 60) + ($mins * 60);
//if sun is not up yet.
if ($time < $this->sunrise) {
echo "sun is not up yet" . PHP_EOL;
$time = $this->sunrise;
}
//if sun has already set.
if ($time > $this->sunset) {
echo "sun has already set" . PHP_EOL;
$time = $this->sunset;
}
//if before mid day
if ($time < $this->midDay) {
//NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
$temperature = (int) ((($time - $this->sunrise) * ($this->Noon - $this->SunRiseSet)) / ($this->midDay - $this->sunrise)) + $this->SunRiseSet;
} else {
//NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
$temperature = (int) ((( $time - $this->midDay) * ( $this->SunRiseSet - $this->Noon )) / ( $this->sunset - $this->midDay )) + $this->Noon;
// echo "temperature is $temperature , time is $time" . PHP_EOL;
}
$this->ph->alert("all", "none");
$this->ph->setColorTemp("all", $temperature, $birghtness, 100);
$this->ph->sendCommands();
}
}
?>
So far performance is what I have expected from the project, after leaving the room I come back to find the room is dark , A few things I want to improve are:
- get a decent project case for this setup.
- find a good placement for it to cover most of the room - yesterday when in bed on laptop the room went dark because i was not in front of asensor.
- make is so that both PIR sensors are facing in different directions as currently they are just stuck on a bread board.
- remove the blue-tack from the LED and dim it in software.