Magic Mirror Software Source Code Snippets
   
  Below are key pieces of the Magic Mirror source code. It will give you a feel for how the Magic Mirror is coded and what you would need to understand in order to modify for your own use.
   
 

Code to handle Arduino Analog Input Events

private function onReceiveAnalogData(e:ArduinoEvent):void {


if (analog_input1 == "on" && SlideShowRunning ==0 && idle_start_playing == 1 && initial_values_done ==1 && video_playing ==0) { //input pin must be turned on and slideshow not running
if (a.getAnalogData(analog_input1_pin) == 0) { //change this back to 0 when the phidget sensor is hooked up
Touch1PressedTimer.start(); //start this timer to make sure its been pressed for 100ms
}
}

if (analog_input2 == "on" && SlideShowRunning ==0 && idle_start_playing == 1 && initial_values_done ==1 && video_playing ==0) { //only if on to avoid ghost readings
if (a.getAnalogData(analog_input2_pin) == 0) {
Touch2PressedTimer.start(); //start this timer to make sure its at 0 for a while
}
}

if (analog_input3 == "on" && SlideShowRunning ==0 && idle_start_playing == 1 && initial_values_done ==1 && video_playing ==0) { //wait for idle video before listening for inputs
if (a.getAnalogData(analog_input3_pin) == 0) { //this is the third touch sensor, plays video1
Touch3PressedTimer.start();
}
}

if (proximity_sensor_on == "on" && SlideShowRunning ==0 && idle_start_playing == 1) { //only if set to on from config file

raw_distance.text = String("Proximity Raw Distance= " + a.getAnalogData(proximity_sensor_pin));
proximity_readout.text = String(a.getAnalogData(proximity_sensor_pin));

if (a.getAnalogData(proximity_sensor_pin) > proximity_sensor_trigger1_distance_lower && a.getAnalogData(proximity_sensor_pin) < proximity_sensor_trigger1_distance_upper ) { //make sure subject is standing in the right spot for a while
proximity_counter++;
if (LEDOffFlag == 1) { //then the LED has been off for long enough so turn it on
LEDOffFlag = 0; //the led is on so turn the flag on, cannot come back until after the LED has been turned off and delay reached
a.writeDigitalPin(AboveFireLed_pin, Arduino.HIGH); //turn on the LED and then use the timer to turn it off
LEDTimer.start(); //start this timer, goes off in 50ms
}
//now let's set a time which will then turn it off, essentially a blink
//trace (proximity_counter);
if (verbose == "yes") {SensorText.text = String("Proximity Match= " + proximity_counter)}; //show the counter in the text box
}

if (proximity_counter == proximity_sensor_trigger1_time && proximity1_do_not_play_again ==0) { //now play the first proximity clip to come closer
FirstProxVideoPlaying = 1; //it gets reset to 0 on clip done routine
a.writeDigitalPin(AboveFireLed_pin, Arduino.HIGH); //turn on the green led above the fire, do not turn off until coming closer
if (x10_commands == "on") {X10_OFF(x10_address1)};
myVid.play(proximity1_clip);
}

if (proximity_flag ==1) { // if close enough, then play the second proxity clip
if (a.getAnalogData(proximity_sensor_pin) < proximity_sensor_trigger2_distance) {
a.writeDigitalPin(AboveFireLed_pin, Arduino.LOW); //they came closer so turn it off now
if (x10_commands == "on") {
X10_OFF(x10_address1);
X10_OFF(x10_address1);
}

if (proximity_flag3 == 0) {
myVid.play(proximity2_clip);
proximity_flag3 = 1;
}
else {
myVid.play(proximity3_clip);
proximity_flag3 = 0;
}
//proximity_counter = 0; //reset all the counters //
proximity_flag = 0; //set this to zero right away so we don't repeat it, the first clip has to play first
}
}
}

if (hardware_mode_select == "on" && SlideShowRunning ==0) {
var num:int;
modeSelect.text = String("Character Select Potentiometer=" + a.getAnalogData(hardware_mode_select_pin)); //pin 4
hardware_mode_select_value = a.getAnalogData(hardware_mode_select_pin); //use this for hardware mode select
num = (initial_hardware_mode_select_value - a.getAnalogData(hardware_mode_select_pin));

var numAbsolute:int = Math.abs(num);

if (numAbsolute > 75) { // was 75, if the change is greater than 175, then check to see if need to change mode
initial_hardware_mode_select_value = a.getAnalogData(hardware_mode_select_pin); //reset the initial value
if (verbose == "yes") {zero_analog.text = String(numAbsolute)};
ModeSelectTimer.start(); //start the timer for 1/2 second
}
}
//} //end if for initial done

} //************************************ end onreceive analog function

private function Touch1PressedTimerEvent(e:TimerEvent):void { //weather
if (a.getAnalogData(analog_input1_pin) == 0) { //now check if its still 0, it had to have been zero for 100ms
if (x10_commands == "on") {
X10_OFF(x10_address1);
}
if (verbose == "yes") {
one_analog.text = "Touched";
touch_counter_text.text = "Touch Counter: " + String(touch_counter);
Touch1Timer.start()//start timer for three seconds and then reset the label
}
touch_counter++; //this tracks how many touches have happened
video_playing = 1; //set the video playing flag
weatherUpdate();
}
}

private function Touch2PressedTimerEvent(e:TimerEvent):void { //stock
if (a.getAnalogData(analog_input2_pin) == 0) { //now check if its still 0, it had to have been zero for 100ms
if (x10_commands == "on") {
X10_OFF(x10_address1);
}
if (verbose == "yes") {
two_analog.text = "Touched";
touch_counter_text.text = "Touch Counter: " + String(touch_counter);
Touch2Timer.start()//start timer for three seconds and then reset the label
}
touch_counter++;
video_playing = 1; //set the video playing flag
stockUpdate();
}
}

private function Touch3PressedTimerEvent(e:TimerEvent):void { //x10 on off
if (a.getAnalogData(analog_input3_pin) == 0) { //now check if its still 0, it had to have been zero for 100ms

if (verbose == "yes") {
three_analog.text = "Touched";
touch_counter_text.text = "Touch Counter: " + String(touch_counter);
Touch3Timer.start()//start timer for three seconds and then reset the label
}
touch_counter++;
video_playing = 1; //set the video playing flag

if (x10_on_off_flag == 0) { //play this one, set the flag which will play the alternative for next time and then back to this
myVid.play(x10_on_clip); //call the x10 commands from the onclip function
x10_on_off_flag = 1;
}
else {
myVid.play(x10_off_clip);
x10_on_off_flag = 0; //reset flag so toggles back on next play
}
}
}

private function Touch1TimerEvent(e:TimerEvent):void {
one_analog.text = "Touch Sensor 1";
Touch1Timer.reset(); //reset the timer
}

private function Touch2TimerEvent(e:TimerEvent):void {
two_analog.text = "Touch Sensor 2";
Touch2Timer.reset(); //reset the timer
}

private function Touch3TimerEvent(e:TimerEvent):void {
three_analog.text = "Touch Sensor 3";
Touch3Timer.reset(); //reset the timer
}

private function ModeSelectTimerEvent(e:TimerEvent):void { //hardware mode select timer function
switch_mode(); //call the switch mode function to change modes
ModeSelectTimer.reset(); //reset the timer
}


private function LEDoff(e:TimerEvent):void { //turns the LED off
if (FirstProxVideoPlaying == 0) { //don't allow turn off if the first proximity video is playing
a.writeDigitalPin(AboveFireLed_pin, Arduino.LOW); //turn LED off
}
LEDTimer.reset(); //reset the timer
LEDTimerOff.start(); //start the other time to control how long the LED is off before turning back on
}

private function LEDon(e:TimerEvent):void { //how long to wait before the LED can be turned back on
LEDOffFlag = 1; //the LED has been off for long enough so now set flag that its ok to turn the LED back on again
LEDTimerOff.reset(); //reset the timer and then its called again when needed above
}

 

Code to handle Arduino Digital Input Events

private function onReceiveDigitalData(e:ArduinoEvent):void {
trace ("received digital data");
//*************************************************************
if (digital_switches == "on") {
if (verbose == "yes") {
two.text = String("Switch 1 - Arduino Digital Pin 2=" + a.getDigitalData(switch1_pin));
three.text = String("Switch 2 - Arduino Digital Pin 3=" + a.getDigitalData(switch2_pin));
four.text = String("Switch 3 - Arduino Digital Pin 4=" + a.getDigitalData(switch3_pin));
seven.text = String("Switch 4 - Arduino Digital Pin 7=" + a.getDigitalData(switch4_pin));
five.text = String("Test Switch 5 - Arduino Digital Pin 5=" + a.getDigitalData(test_switch_pin));
}
///**************write the values of the switches to variables ********
///************* the inital variables are stored in the one time routine*****

door_value=a.getDigitalData(switch1_pin)
side_window_value= a.getDigitalData(switch2_pin);
front_window_value= a.getDigitalData(switch3_pin);
idol_value = a.getDigitalData(switch4_pin);

if (test_switch == "on" && SlideShowRunning ==0 && initial_values_done == 1) {
if (x10_commands == "on") {X10_OFF(x10_address1)};
if (a.getDigitalData(test_switch_pin) == 1) { //pin 5
weatherUpdate();
}
}

if (switch1 == "on") {
if (initial_door_value != door_value && SlideShowRunning ==0 && initial_values_done == 1) {
if (x10_commands == "on") {X10_OFF(x10_address1)};
myVid.play(doorbell_clip);
initial_door_value = door_value; //now set them equal in prep for the next change
}
}


if (switch3 == "on") {
if (initial_front_window_value != front_window_value && SlideShowRunning ==0 && initial_values_done == 1) { //pin 4
if (x10_commands == "on") {X10_OFF(x10_address1)};
stockUpdate();
initial_front_window_value = front_window_value; // now set it to equal
}
}

/*********************************

if (switch4 == "on") {
if (a.getDigitalData(switch4_pin) == 0) { //the idol was picked up
StartSlideShow();
}
else {
StopSlideShow();
}
}

} // end if digital switches on
// } // end if initial values
} // ************end digial inputs function

 

Weather Function

private function weather():void {
switch (weather_code) //sets the video playlists based on the mode
{
case "0": //tornado
myVid.play(weather_rain_clip);
break;
case "1": //tropical storm
myVid.play(weather_rain_clip);
break;
case "2": //hurricane
myVid.play(weather_rain_clip);
break;
case "3": //severe thunderstorms
myVid.play(weather_rain_clip);
break;
case "4": //thunderstorms
myVid.play(weather_rain_clip);
break;
case "5": //mixed rain and snow
myVid.play(weather_rain_clip);
break;
case "6": //mised rain and sleet
myVid.play(weather_rain_clip);
break;
case "7": //mised snow and sleet
myVid.play(weather_rain_clip);
break;
case "8": //freezing drizzle
myVid.play(weather_rain_clip);
break;
case "9": //drizzle
myVid.play(weather_rain_clip);
break;
case "10": //freezing rain
myVid.play(weather_rain_clip);
break;
case "11": //showers
myVid.play(weather_rain_clip);
break;
case "12": //showers
myVid.play(weather_rain_clip);
break;
case "13": //snow flurries
myVid.play(weather_rain_clip);
break;
case "14": //light snow showers
myVid.play(weather_rain_clip);
break;
case "15": //blowing snow
myVid.play(weather_rain_clip);
break;
case "16": //snow
myVid.play(weather_rain_clip);
break;
case "17": //hail
myVid.play(weather_rain_clip);
break;
case "18": //sleet
myVid.play(weather_rain_clip);
break;
case "19": //dust
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "20": //foggy
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "21": //haze
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "22": //smoky
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "23": //blustery
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "24": //windy
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "25": //cold
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "26": //cloudy
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "27": //mostly cloudy (day)
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "28": //mostly cloudy (night)
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "29": //partly cloudy (night)
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "30": //partly cloudy (day)
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "31": //clear (night)
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "32": //sunny
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "33": //fair (night)
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "34": //fair (day)
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "35": //mixed rain and hail
myVid.play(weather_rain_clip);
break;
case "36": //hot
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "37": //isoldated thunderstorms
myVid.play(weather_rain_clip);
break;
case "38": //scattered thunderstorms
myVid.play(weather_rain_clip);
break;
case "39": //scattered thunderstorms
myVid.play(weather_rain_clip);
break;
case "40": //scattered showers
myVid.play(weather_rain_clip);
break;
case "41": //heavy snow
myVid.play(weather_rain_clip);
break;
case "42": //scattered snow showers
myVid.play(weather_rain_clip);
break;
case "43": //heavy snow
myVid.play(weather_rain_clip);
break;
case "44": //partly cloudy
if (weather_high > good_weather_threshold) {
myVid.play(weather_good_clip); }
else {myVid.play(weather_ok_clip);}
break;
case "45": //thundershowers
myVid.play(weather_rain_clip);
break;
case "46": //snow showers
myVid.play(weather_rain_clip);
break;
case "47": //isoldated thundershowers
myVid.play(weather_rain_clip);
break;
case "3200": //not available
myVid.play(weather_ok_clip);
break;
default:
myVid.play(no_internet_clip);
} //end case

} //end weather function

private function WeatherDisplayTextTimerEvent(e:TimerEvent):void {

if (display_weather_text == "on") {
weather_display2.visible = true;
weather_display2.text = WeatherForecastText;
}
if (display_weather_image == "on") {
weather_image.visible = true;
}
WeatherDisplayTextTimer.reset(); //reset the timer so it can play again
WeatherDisplayTextTimer5s.start(); //start the 5 second timer
}

private function WeatherDisplayTextTimerEvent5s(e:TimerEvent):void {
weather_display2.visible = false; //its been 5s so now turn off the text
weather_image.visible = false;
WeatherDisplayTextTimer5s.reset(); //start the 5 second timer
}

private function WeatherLoaderioErrorHandler(event:IOErrorEvent):void {
trace("Weather Loader Error Trapped ioErrorHandler: " + event);
WeatherText.text = "Weather Internet call failed, check Internet connection or Yahoo Weather API unavailable";
myVid.play(no_internet_clip);
}

 

Stock Function

private function stock():void {

if (stockPriceChange > stock_good_threshold) {
myVid.play(stock_up_clip)
Stock.text = ("Stock is Up");
StockTextFormat.color = 0x00CC33; //green
//stock_display.backgroundColor = 0x00CC33; //green background
}
if (stockPriceChange < stock_bad_threshold) {
myVid.play(stock_down_clip);
Stock.text = ("Stock is Down");
StockTextFormat.color = 0xFF0033; //red
//stock_display.backgroundColor = 0xFF0033; //white background
}
if ((stockPriceChange < stock_good_threshold) && (stockPriceChange > stock_bad_threshold)) {
myVid.play(stock_no_change_clip);
var myBool:Boolean ;
myBool = (stockPriceChange < stock_good_threshold && stockPriceChange > stock_bad_threshold);
trace (stock_good_threshold + " " + stock_bad_threshold);
trace ("stock boolean " + myBool);
Stock.text = ("Stock No Change");
StockTextFormat.color = 0xF5F5F5; //white
//stock_display.backgroundColor = 0xF5F5F5; //white background
}
if (display_stock_text == "on") { //only display the stock text if set to on
StockDisplayTextTimer.start(); //start the timer to delay 1 second before displaying stock text
}
}

private function StockDisplayTextTimerEvent(e:TimerEvent):void {
stock_display.visible = true;
stock_display.defaultTextFormat = StockTextFormat; //need to reapply this again since we changed the font colors above
if (stockPriceChange > 0) { //the number is postive
stock_display.text = ("+" + String(stockPriceChange)); //displays the stock text;
StockDisplayTextTimer.reset(); //reset the timer so it can play again
}

else {
stock_display.text = String(stockPriceChange); //displays the stock text;
StockDisplayTextTimer.reset(); //reset the timer so it can play again
}
StockDisplayTextTimer5s.start();
}

private function StockDisplayTextTimerEvent5s(e:TimerEvent):void {
stock_display.visible = false; //its been 5s so now turn off the text
StockDisplayTextTimer5s.reset(); //start the 5 second timer
}


private function stockLoaderioErrorHandler(event:IOErrorEvent):void {
trace("Stock Loader Error Trapped ioErrorHandler: " + event);
Stock.text = "Stock Internet call failed, check Internet connection or Yahoo Stock API unavailable";
myVid.play(no_internet_clip);
}

 

 

X-10 commands to interface with the X-10 CM17A

private function X10_ON(address:String):void {
var x10_on_address = address;
x10_last = address;
Get_X10_Array(x10_on_address); //pass the x10 on address to the x10 get array function
x10_array = X10_ON_ARRAY; //the x10 array function ran and now we can assign the array
x10_array.push (1,0,1,0,1,1,0,1); //add these to the end of the array, its the last x10 byte
x10_array.unshift(1,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0); //add these to the beginning of the array
X10(); //call the actual x10 function using the x10_array that was obtained from the get x10 array function call
x10_label.text = String("Last X10 Command: " + x10_last + " ON");
trace ("Last x10 Command: " + address + " ON");
trace ("X10 ON ARRAY: " + X10_ON_ARRAY);
trace ("x10_array: " + x10_array);
} //end function

private function X10_OFF(address:String):void {
var x10_off_address = address;
x10_last = address;
Get_X10_Array(x10_off_address); //pass the x10 on address to the x10 get array function
x10_array = X10_OFF_ARRAY; //the x10 array function ran and now we can assign the array
x10_array.push (1,0,1,0,1,1,0,1); //add these to the end of the array, its the last x10 byte
x10_array.unshift(1,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0); //add these to the beginning of the array
X10(); //call the actual x10 function using the x10_array that was obtained from the get x10 array function call
x10_label.text = String("Last X10 Command: " + x10_last + " OFF");
trace ("Last x10 Command: " + address + " OFF");
trace ("X10 OFF ARRAY: " + X10_OFF_ARRAY);
trace ("x10_array: " + x10_array);
} //end function

private function X10_BRIGHT(address:String):void {
var x10_bright_address = address;
x10_last = address;
Get_X10_Array_BrightDim(x10_bright_address); //pass the x10 on address to the x10 get array function
x10_array = X10_BRIGHT_ARRAY; //the x10 array function ran and now we can assign the array
x10_array.push (1,0,1,0,1,1,0,1); //add these to the end of the array, its the last x10 byte
x10_array.unshift(1,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0); //add these to the beginning of the array
X10(); //call the actual x10 function using the x10_array that was obtained from the get x10 array function call
x10_label.text = String("Last X10 Command: " + x10_last + " BRIGHT");
trace ("Last x10 Command: " + address + " ON");
trace ("X10 BRIGHT ARRAY: " + X10_BRIGHT_ARRAY);
trace ("x10_array: " + x10_array);
} //end function

private function X10_DIM(address:String):void {
var x10_dim_address = address;
x10_last = address;
Get_X10_Array_BrightDim(x10_dim_address); //pass the x10 on address to the x10 get array function
x10_array = X10_DIM_ARRAY; //the x10 array function ran and now we can assign the array
x10_array.push (1,0,1,0,1,1,0,1); //add these to the end of the array, its the last x10 byte
x10_array.unshift(1,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0); //add these to the beginning of the array
trace ("X10 DIM ARRAY: " + X10_DIM_ARRAY);
X10(); //call the actual x10 function using the x10_array that was obtained from the get x10 array function call
x10_label.text = String("Last X10 Command: " + x10_last + " DIM");
} //end function

private function X10():void {
x10_in_progress = 1; //set this flag so nothing else happens until this function is done
x10_counter = 0; //make sure to set this to zero to start
a.writeDigitalPin(DTR_pin,Arduino.LOW);
a.writeDigitalPin(RTS_pin,Arduino.LOW);
x10_sleep_initial.start(); //sleep for 1 ms and then set to high
} //end function

///*************** x10 timer functions
private function x10_sleep_initial_event(e:TimerEvent):void {
//***** Put firecracker into standby mode *******
a.writeDigitalPin(DTR_pin,Arduino.HIGH);
a.writeDigitalPin(RTS_pin,Arduino.HIGH);
x10_sleep_initial.reset(); //reset the timer
x10_sleep35.start();
}

private function x10_sleep35_event(e:TimerEvent):void { //delay 35ms before sending the packet
x10_sleep35.reset();
x10_main(); //call the x10 main function to start writing bits
}

private function x10_main():void {
if (x10_counter < 40) {
if (x10_array[x10_counter]==1) {
a.writeDigitalPin(DTR_pin, Arduino.LOW); // 1 = RTS HIGH/DTR-LOW
x10_counter++;
x10_done1.start();

}
else {
a.writeDigitalPin(RTS_pin, Arduino.LOW);
x10_counter++;
x10_done1.start();
}
}
else {
x10_sleep1000.start(); //done with the 40 bits so now wait a second
}
} //end x10 main function

private function x10_done1_event(e:TimerEvent):void {
a.writeDigitalPin(DTR_pin,Arduino.HIGH);
a.writeDigitalPin(RTS_pin,Arduino.HIGH);
x10_done1.reset();
x10_done2.start();
}

private function x10_done2_event(e:TimerEvent):void {
x10_done2.reset();
x10_main();
}

private function x10_sleep1000_event(e:TimerEvent):void {
x10_in_progress = 0; // now clear this so other videos can play
x10_sleep1000.reset();
}

 
 
 

Paypal Payment

A software registration key and the software source code will be e-mailed to you after your Paypal payment has been received.

Creative Commons License
The DIY Magic Mirror hardware and software is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
Contact us for permissions beyond the scope of this license.

Home | Hardware | Software | Contact Us Copyright DIY Magic Mirror